--- /dev/null
+Makefile.in
+Makefile
+*.o
+*.lo
+*.la
+*.c
+*.h
+*.stamp
+*.gir
+.deps
++.dirstamp
+.libs
+libvala-*.vapi
+
+config.*
+aclocal.m4
+autom4te.cache
+ChangeLog
+configure
+depcomp
+INSTALL
+install-sh
+libtool
+m4
+missing
+ltmain.sh
+ylwrap
+compile
+stamp-h1
+*.pc
+.tarball-version
+.version
+
+*.gcda
+*.gcno
+coverage
+lcov.info
+
+*~
+
+build-aux/test-driver
+
+tests/_test
+
--- /dev/null
+ACLOCAL_AMFLAGS = --install -I m4 ${ACLOCAL_FLAGS}
+
+NULL =
+
+SUBDIRS = \
+ gee \
+ vala \
+ ccode \
+ codegen \
+ compiler \
+ vapi \
+ tests \
+ doc \
+ gobject-introspection \
+ vapigen \
++ libvaladoc \
++ valadoc \
+ $(NULL)
+
+if ENABLE_UNVERSIONED
+aclocaldir = $(datadir)/aclocal
+aclocal_DATA = vala.m4
+endif
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libvala@PACKAGE_SUFFIX@.pc
+
+libvala@PACKAGE_SUFFIX@.pc: libvala.pc
+ cp $< $@
+
+.PHONY: bootstrap
+bootstrap: all
+ find $(top_srcdir) -name "*.vala.stamp" | xargs rm -f
+ $(MAKE) $(AM_MAKEFLAGS) all VALAC=$(abs_top_builddir)/compiler/valac$(EXEEXT) V=$V
+
+.PHONY: test
+test:
+ cd tests && $(MAKE) $(AM_MAKEFLAGS) check
+
+#if ENABLE_COVERAGE
+.PHONY: coverage coverage-report
+coverage:
+ find $(top_srcdir) -name "*.gcda" | xargs rm -f
+ $(MAKE) $(AM_MAKEFLAGS) bootstrap
+ $(MAKE) $(AM_MAKEFLAGS) test
+
+coverage-report: coverage
+ lcov --directory $(top_srcdir) --capture --output-file $(top_builddir)/lcov.info
+ lcov --directory $(top_srcdir) --output-file $(top_builddir)/lcov.info --remove $(top_builddir)/lcov.info "*.c" "*.h" "*.vapi"
+ rm -rf $(top_builddir)/coverage
+ $(mkdir_p) $(top_builddir)/coverage
+ genhtml --title "@PACKAGE_STRING@" --output-directory $(top_builddir)/coverage $(top_builddir)/lcov.info
+#endif
+
+all: version.h
+
+version.h: $(top_srcdir)/.version
+ echo '#define BUILD_VERSION "'`cat $(top_srcdir)/.version`'"' > $@-t && mv $@-t $@
+
+BUILT_SOURCES = $(top_srcdir)/.version
+$(top_srcdir)/.version: gen-version
+ @true
+.PHONY: gen-version
+gen-version:
+ @V=`$(top_srcdir)/build-aux/git-version-gen $(top_srcdir)/.tarball-version` && \
+ if [ -e $(top_srcdir)/.version ] && [ "x`cat $(top_srcdir)/.version`" = "x$$V" ]; then \
+ true; \
+ else \
+ echo "$$V" > $(top_srcdir)/.version; \
+ fi
+dist-hook: gen-ChangeLog
+ echo $(VERSION) > $(distdir)/.tarball-version
+
+gen_start_date = 2009-02-25
+.PHONY: gen-ChangeLog
+gen-ChangeLog:
+ if test -d .git; then \
+ $(top_srcdir)/build-aux/gitlog-to-changelog \
+ --since=$(gen_start_date) > $(distdir)/cl-t; \
+ rm -f $(distdir)/ChangeLog; \
+ mv $(distdir)/cl-t $(distdir)/ChangeLog; \
+ fi
+
+CLEANFILES = \
+ libvala@PACKAGE_SUFFIX@.pc \
+ $(NULL)
+
+EXTRA_DIST = \
+ ChangeLog.pre-0-4 \
+ ChangeLog.pre-0-5-7 \
+ libvala.pc.in \
+ vala.m4 \
+ .version \
+ build-aux/git-version-gen \
+ build-aux/gitlog-to-changelog \
+ $(NULL)
+
+DISTCLEANFILES = version.h
--- /dev/null
- AM_INIT_AUTOMAKE([1.11 dist-xz no-dist-gzip])
+AC_PREREQ([2.65])
+AC_INIT([vala], m4_esyscmd([build-aux/git-version-gen .tarball-version]),
+ [https://bugzilla.gnome.org/browse.cgi?product=vala],
+ [vala],
+ [https://wiki.gnome.org/Projects/Vala])
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_HEADERS(config.h)
+AC_CONFIG_MACRO_DIR([m4])
- vapigen/vala-gen-introspect/vala-gen-introspect])
++AM_INIT_AUTOMAKE([1.11 dist-xz no-dist-gzip subdir-objects])
+AM_MAINTAINER_MODE([enable])
+
+API_VERSION=0.38
+PACKAGE_SUFFIX="-$API_VERSION"
+
+dnl http://people.gnome.org/~walters/docs/build-api.txt
+dnl We don't support separate builddir when building from git
+echo \#buildapi-variable-no-builddir >/dev/null
+
+AC_SUBST(API_VERSION)
+AC_DEFINE_UNQUOTED(API_VERSION, "$API_VERSION", [Define to the api-version of this package])
+AC_SUBST(PACKAGE_SUFFIX)
+AC_DEFINE_UNQUOTED(PACKAGE_SUFFIX, "$PACKAGE_SUFFIX", [Define to the suffix of this package])
+
+program_transform_name="s,\$\$,${PACKAGE_SUFFIX},"
+
+AC_SUBST(pkgdatadir, [${datadir}/vala${PACKAGE_SUFFIX}])
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_LN_S
+AC_PROG_INSTALL
+AC_PROG_MKDIR_P
+
+LT_PREREQ([2.2.6])
+LT_INIT([disable-static])
+PKG_PROG_PKG_CONFIG([0.21])
+
+AC_PROG_LEX
+if test "$LEX" = :; then
+ AC_MSG_ERROR([flex not found but required])
+fi
+
+AC_CHECK_PROGS(YACC, 'bison -y' byacc yacc, :)
+if test "$YACC" = :; then
+ AC_MSG_ERROR([bison not found but required])
+fi
+
+AC_PATH_PROG(VALAC, valac, valac)
+AC_SUBST(VALAC)
+
+VALAC_BOOTSTRAP_REQUIRED=0.25.1
+
+AS_IF([test "$VALAC" != valac], [FOUND_VALAC_VERION=`$VALAC --version | sed 's/Vala *//'`
+ AS_VERSION_COMPARE(["$VALAC_BOOTSTRAP_REQUIRED"], ["$FOUND_VALAC_VERION"],
+ [enable_boostrap=yes], [enable_boostrap=yes], [enable_boostrap=no])])
+
+VALAFLAGS="$VALAFLAGS --disable-version-header"
+if test x$enable_boostrap = xyes; then
+ VALAFLAGS="$VALAFLAGS --hide-internal"
+fi
+
+AC_SUBST(VALAFLAGS)
+AC_SUBST(CFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+
+AC_ARG_ENABLE(unversioned, AS_HELP_STRING([--disable-unversioned], [Disable unversioned binaries]), enable_unversioned=$enableval, enable_unversioned=yes)
+AM_CONDITIONAL(ENABLE_UNVERSIONED, test x$enable_unversioned = xyes)
+
+AC_ARG_ENABLE(coverage, AS_HELP_STRING([--enable-coverage], [Enable coverage analysis]), enable_coverage=$enableval, enable_coverage=no)
+AM_CONDITIONAL(ENABLE_COVERAGE, test x$enable_coverage = xyes)
+
+if test "$enable_coverage" = "yes"; then
+ COVERAGE_VALAFLAGS="-g"
+ COVERAGE_CFLAGS="-fprofile-arcs -ftest-coverage"
+ COVERAGE_LIBS="-lgcov"
+else
+ COVERAGE_VALAFLAGS=
+ COVERAGE_CFLAGS=
+ COVERAGE_LIBS=
+fi
+AC_SUBST(COVERAGE_VALAFLAGS)
+AC_SUBST(COVERAGE_CFLAGS)
+AC_SUBST(COVERAGE_LIBS)
+
+GLIB_REQUIRED=2.40.0
++LIBGVC_REQUIRED=2.16
+
+PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED gobject-2.0 >= $GLIB_REQUIRED)
+
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+PKG_CHECK_MODULES(GMODULE, gmodule-2.0 >= $GLIB_REQUIRED)
+
+AC_SUBST(GMODULE_CFLAGS)
+AC_SUBST(GMODULE_LIBS)
+
++PKG_CHECK_MODULES(LIBGVC, libgvc >= $LIBGVC_REQUIRED)
++AC_MSG_CHECKING([for CGRAPH])
++cgraph_tmp_LIBADD="$LIBADD"
++cgraph_tmp_CFLAGS="$CFLAGS"
++LIBADD="$LIBADD $LIBGVC_LIBS"
++CFLAGS="$CFLAGS $LIBGVC_CFLAGS"
++AC_RUN_IFELSE(
++ [AC_LANG_SOURCE([
++ #include <gvc.h>
++
++ int main(void) {
++ #ifdef WITH_CGRAPH
++ return 0;
++ #else
++ return -1;
++ #endif
++ }
++ ])], [
++ AC_MSG_RESULT([yes])
++ VALAFLAGS="$VALAFLAGS -D WITH_CGRAPH"
++ have_cgraph=yes
++ ], [
++ AC_MSG_RESULT([no])
++ have_cgraph=no
++ ]
++)
++LIBADD="$cgraph_tmp_LIBADD"
++CFLAGS="$cgraph_tmp_CFLAGS"
++AM_CONDITIONAL(HAVE_CGRAPH, test "$have_cgraph" = "yes")
++
+AC_PATH_PROG([XSLTPROC], [xsltproc], :)
+AM_CONDITIONAL(HAVE_XSLTPROC, test "$XSLTPROC" != :)
+
+AC_CHECK_PROG([WEASYPRINT], [weasyprint], [weasyprint])
+AM_CONDITIONAL(HAVE_WEASYPRINT, [test x$WEASYPRINT = xweasyprint])
+
+AC_CHECK_PROG([HELP2MAN], [help2man], [help2man])
+AM_CONDITIONAL([HAVE_HELP2MAN], [test x$HELP2MAN = xhelp2man])
+
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+
+AC_CONFIG_FILES([Makefile
+ libvala.pc
+ gee/Makefile
+ ccode/Makefile
+ vala/Makefile
+ codegen/Makefile
+ compiler/Makefile
+ vapi/Makefile
+ tests/Makefile
+ doc/Makefile
+ doc/manual/Makefile
+ doc/manual/version.xml
+ gobject-introspection/Makefile
+ vapigen/vapigen.pc
+ vapigen/Makefile
+ vapigen/vala-gen-introspect/Makefile
++ vapigen/vala-gen-introspect/vala-gen-introspect
++ libvaladoc/valadoc.pc
++ libvaladoc/valadoc.deps
++ libvaladoc/Makefile
++ valadoc/Makefile
++ valadoc/doclets/Makefile
++ valadoc/doclets/html/Makefile
++ valadoc/doclets/devhelp/Makefile
++ valadoc/doclets/gtkdoc/Makefile
++ valadoc/icons/Makefile
++ valadoc/tests/Makefile
++])
+
+AC_OUTPUT
--- /dev/null
- manpages: valac.1 vala-gen-introspect.1 vapigen.1
+NULL =
+
+SUBDIRS = \
+ manual \
+ $(NULL)
+
+dist_man_MANS = \
+ valac.1 \
++ valadoc.1 \
+ vala-gen-introspect.1 \
+ vapigen.1 \
+ $(NULL)
+
+EXTRA_DIST = \
+ valac.h2m \
++ valadoc.h2m \
+ vala-gen-introspect.h2m \
+ vapigen.h2m \
+ $(NULL)
+
+if HAVE_HELP2MAN
++manpages: valac.1 valadoc.1 vala-gen-introspect.1 vapigen.1
+ @rm $^
+ $(MAKE) $(AM_MAKEFLAGS) $^
+
+valac.1:
+ $(HELP2MAN) $(top_builddir)/compiler/valac \
+ --include $(srcdir)/valac.h2m \
+ --libtool --no-info \
+ --output=$@
++valadoc.1:
++ $(HELP2MAN) $(top_builddir)/valadoc/valadoc \
++ --include $(srcdir)/valadoc.h2m \
++ --libtool --no-info \
++ --output=$@
+vala-gen-introspect.1:
+ $(HELP2MAN) $(top_builddir)/gobject-introspection/gen-introspect \
+ --include $(srcdir)/vala-gen-introspect.h2m \
+ --version-string=$(PACKAGE_VERSION) \
+ --libtool --no-info \
+ --output=$@
+vapigen.1:
+ $(HELP2MAN) $(top_builddir)/vapigen/vapigen \
+ --include $(srcdir)/vapigen.h2m \
+ --libtool --no-info \
+ --output=$@
+endif
+
+if ENABLE_UNVERSIONED
+install-data-hook:
+ cd $(DESTDIR)$(man1dir) && $(LN_S) -f valac@PACKAGE_SUFFIX@.1 valac.1
++ cd $(DESTDIR)$(man1dir) && $(LN_S) -f valadoc@PACKAGE_SUFFIX@.1 valadoc.1
+ cd $(DESTDIR)$(man1dir) && $(LN_S) -f vala-gen-introspect@PACKAGE_SUFFIX@.1 vala-gen-introspect.1
+ cd $(DESTDIR)$(man1dir) && $(LN_S) -f vapigen@PACKAGE_SUFFIX@.1 vapigen.1
+endif
--- /dev/null
--- /dev/null
++valadoc*.deps
++valadoc*.vapi
--- /dev/null
-NULL =
++include $(top_srcdir)/Makefile.common
+
-DEFAULT_DRIVER = $(shell $(VALAC) --api-version >/dev/null 2>&1; if [ $$? = 0 ]; then $(VALAC) --api-version; else $(VALAC) --version; fi)
++NULL =
+
+ AM_CFLAGS = \
+ -DPACKAGE_ICONDIR=\"$(datadir)/valadoc/icons/\" \
+ -DPACKAGE_DATADIR=\"$(libdir)/valadoc\" \
+ -DPACKAGE_VERSION=\"$(VERSION)\" \
- -DDEFAULT_DRIVER=\"$(DEFAULT_DRIVER)\" \
+ $(LIBGVC_CFLAGS) \
+ $(GLIB_CFLAGS) \
- $(LIBGEE_CFLAGS) \
+ $(GMODULE_CFLAGS) \
- -g \
- -w \
++ -I$(top_srcdir)/gee \
+ $(NULL)
+
+ AM_VALAFLAGS = \
- $(VALAFLAGS) \
- --vapidir $(top_srcdir)/src/vapi/ \
- --basedir $(srcdir) \
- --directory $(builddir) \
- -C \
- -g \
+ $(NULL)
+
+ BUILT_SOURCES = \
+ libvaladoc.vala.stamp \
- valadoc-1.0.h \
++ valadoc.h \
+ $(NULL)
+
-lib_LTLIBRARIES = libvaladoc.la
++lib_LTLIBRARIES = libvaladoc@PACKAGE_SUFFIX@.la
+
+ libvaladoc_la_VALASOURCES = \
+ doclet.vala \
+ errorreporter.vala \
+ filehelper.vala \
+ moduleloader.vala \
+ settings.vala \
+ markupwriter.vala \
+ gtkdocmarkupwriter.vala \
+ devhelp-markupwriter.vala \
+ ctyperesolver.vala \
+ markupsourcelocation.vala \
+ markuptokentype.vala \
+ markupreader.vala \
+ gtkdocrenderer.vala \
+ documentation/commentscanner.vala \
+ documentation/documentation.vala \
+ documentation/documentationparser.vala \
+ documentation/wiki.vala \
+ documentation/wikiscanner.vala \
+ documentation/gtkdoccommentparser.vala \
+ documentation/gtkdoccommentscanner.vala \
+ documentation/gtkdocmarkdownparser.vala \
+ documentation/gtkdocmarkdownscanner.vala \
+ documentation/importerhelper.vala \
+ documentation/girmetadata.vala \
+ importer/documentationimporter.vala \
+ importer/valadocdocumentationimporter.vala \
+ importer/valadocdocumentationimporterscanner.vala \
+ importer/girdocumentationimporter.vala \
+ importer/internalidregistrar.vala \
+ api/symbolaccessibility.vala \
+ api/sourcecomment.vala \
+ api/girsourcecomment.vala \
+ api/attributeargument.vala \
+ api/attribute.vala \
+ api/array.vala \
+ api/callable.vala \
+ api/childsymbolregistrar.vala \
+ api/class.vala \
+ api/constant.vala \
+ api/delegate.vala \
+ api/enum.vala \
+ api/enumvalue.vala \
+ api/errorcode.vala \
+ api/errordomain.vala \
+ api/field.vala \
+ api/formalparameter.vala \
+ api/formalparametertype.vala \
+ api/interface.vala \
+ api/item.vala \
+ api/member.vala \
+ api/method.vala \
+ api/methodbindingtype.vala \
+ api/namespace.vala \
+ api/node.vala \
+ api/nodetype.vala \
+ api/ownership.vala \
+ api/package.vala \
+ api/pointer.vala \
+ api/property.vala \
+ api/propertyaccessor.vala \
+ api/propertyaccessortype.vala \
+ api/propertybindingtype.vala \
+ api/signal.vala \
+ api/signaturebuilder.vala \
+ api/sourcefile.vala \
+ api/struct.vala \
+ api/symbol.vala \
+ api/tree.vala \
+ api/typeparameter.vala \
+ api/typereference.vala \
+ api/typesymbol.vala \
+ api/browsable.vala \
+ api/visitor.vala \
+ api/driver.vala \
+ content/block.vala \
+ content/blockcontent.vala \
+ content/comment.vala \
+ content/contentfactory.vala \
+ content/contentelement.vala \
+ content/contentrenderer.vala \
+ content/contentvisitor.vala \
+ content/embedded.vala \
+ content/headline.vala \
+ content/inline.vala \
+ content/inlinetaglet.vala \
+ content/inlinecontent.vala \
+ content/wikilink.vala \
+ content/link.vala \
+ content/list.vala \
+ content/listitem.vala \
+ content/page.vala \
+ content/paragraph.vala \
+ content/warning.vala \
+ content/note.vala \
+ content/resourcelocator.vala \
+ content/run.vala \
+ content/sourcecode.vala \
+ content/styleattributes.vala \
+ content/symbollink.vala \
+ content/table.vala \
+ content/tablecell.vala \
+ content/tablerow.vala \
+ content/taglet.vala \
+ content/text.vala \
+ charts/chart.vala \
+ charts/chartfactory.vala \
+ charts/hierarchychart.vala \
+ charts/simplechartfactory.vala \
+ parser/manyrule.vala \
+ parser/oneofrule.vala \
+ parser/optionalrule.vala \
+ parser/parser.vala \
+ parser/parsercallback.vala \
+ parser/rule.vala \
+ parser/scanner.vala \
+ parser/sequencerule.vala \
+ parser/sourcelocation.vala \
+ parser/stubrule.vala \
+ parser/token.vala \
+ parser/tokentype.vala \
+ taglets/tagletdeprecated.vala \
+ taglets/tagletinheritdoc.vala \
+ taglets/tagletinit.vala \
+ taglets/tagletlink.vala \
+ taglets/tagletparam.vala \
+ taglets/tagletreturn.vala \
+ taglets/tagletsee.vala \
+ taglets/tagletsince.vala \
+ taglets/tagletthrows.vala \
+ highlighter/scanner.vala \
+ highlighter/codescanner.vala \
+ highlighter/xmlscanner.vala \
+ highlighter/codetoken.vala \
+ highlighter/highlighter.vala \
+ html/basicdoclet.vala \
+ html/htmlchartfactory.vala \
+ html/linkhelper.vala \
+ html/cssclassresolver.vala \
+ html/htmlmarkupwriter.vala \
+ html/htmlrenderer.vala \
+ $(NULL)
+
-nodist_libvaladoc_la_SOURCES = \
++libvaladoc@PACKAGE_SUFFIX@_la_SOURCES = \
++ libvaladoc.vala.stamp \
+ $(libvaladoc_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
-valadoc-1.0.vapi valadoc-1.0.h: libvaladoc.vala.stamp
-libvaladoc.vala.stamp: $(libvaladoc_la_VALASOURCES) Makefile
- $(VALAC) \
- $(AM_VALAFLAGS) \
- -H valadoc-1.0.h \
- --library valadoc-1.0 \
- --vapi valadoc-1.0.vapi \
++valadoc@PACKAGE_SUFFIX@.vapi valadoc.h: libvaladoc.vala.stamp
++libvaladoc.vala.stamp: $(libvaladoc_la_VALASOURCES)
++ $(VALA_V)$(VALAC) \
++ $(VALAFLAGS) \
++ --basedir $(srcdir) \
++ --directory $(builddir) \
++ -C \
++ -H valadoc.h \
++ --library valadoc \
++ --vapi valadoc@PACKAGE_SUFFIX@.vapi \
++ --vapidir $(top_srcdir)/vapi --pkg gmodule-2.0 \
++ --vapidir $(top_srcdir)/valadoc/vapi --pkg libgvc \
++ --vapidir $(top_srcdir)/gee --pkg gee \
+ --pkg config \
- --pkg gee-0.8 \
- --pkg gmodule-2.0 \
- --pkg libgvc \
+ $(filter %.vala %.c,$^)
+ touch $@
+
-libvaladoc_la_LDFLAGS = -no-undefined
++libvaladoc@PACKAGE_SUFFIX@_la_LDFLAGS = \
++ -no-undefined \
++ $(NULL)
+
-libvaladoc_la_LIBADD = \
++libvaladoc@PACKAGE_SUFFIX@_la_LIBADD = \
+ $(LIBGVC_LIBS) \
- $(LIBGEE_LIBS) \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
++ $(top_builddir)/vala/libvala@PACKAGE_SUFFIX@.la \
+ $(NULL)
+
-libvaladocincludedir = $(includedir)/
-nodist_libvaladocinclude_HEADERS = \
- valadoc-1.0.h \
++libvaladocincludedir = $(includedir)/valadoc@PACKAGE_SUFFIX@
++libvaladocinclude_HEADERS = \
++ valadoc.h \
+ $(NULL)
+
+ pkgconfigdir = $(libdir)/pkgconfig
-nodist_pkgconfig_DATA = valadoc-1.0.pc
++nodist_pkgconfig_DATA = valadoc@PACKAGE_SUFFIX@.pc
++
++valadoc@PACKAGE_SUFFIX@.pc: valadoc.pc
++ cp $< $@
+
+ vapidir = $(datadir)/vala/vapi
-nodist_vapi_DATA = \
- valadoc-1.0.vapi \
- valadoc-1.0.deps \
- $(NULL)
++dist_vapi_DATA = valadoc@PACKAGE_SUFFIX@.vapi
++nodist_vapi_DATA = valadoc@PACKAGE_SUFFIX@.deps
++
++valadoc@PACKAGE_SUFFIX@.deps: valadoc.deps
++ cp $< $@
+
+ EXTRA_DIST = \
+ $(libvaladoc_la_VALASOURCES) \
- valadoc-1.0.deps.in \
- valadoc-1.0.pc.in \
++ libvaladoc.vala.stamp \
++ valadoc.deps.in \
++ valadoc.pc.in \
+ $(NULL)
+
+ CLEANFILES = \
- $(BUILT_SOURCES) \
- $(nodist_libvaladoc_la_SOURCES) \
- valadoc-1.0.deps \
- valadoc-1.0.pc \
- valadoc-1.0.vapi \
- valadoc-1.0.h \
++ valadoc@PACKAGE_SUFFIX@.deps \
++ valadoc@PACKAGE_SUFFIX@.pc \
++ $(NULL)
++
++MAINTAINERCLEANFILES = \
++ valadoc.deps \
++ valadoc.pc \
++ valadoc.vapi \
++ valadoc.h \
++ $(libvaladoc_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* array.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents an array declaration.
+ */
+ public class Valadoc.Api.Array : Item {
+
+ /**
+ * The element type.
+ */
+ public Item data_type {
+ set;
+ get;
+ }
+
+ public Array (Item parent, void* data) {
+ base (data);
+
+ this.parent = parent;
+ }
+
+ private inline bool element_is_owned () {
+ TypeReference reference = data_type as TypeReference;
+ if (reference == null) {
+ return true;
+ }
+
+ return !reference.is_unowned && !reference.is_weak;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ SignatureBuilder builder = new SignatureBuilder ();
+ if (element_is_owned ()) {
+ builder.append_content (data_type.signature);
+ } else {
+ builder.append ("(", false);
+ builder.append_content (data_type.signature, false);
+ builder.append (")", false);
+ }
+ builder.append ("[]", false);
+ return builder.get ();
+ }
+ }
--- /dev/null
-using Valadoc.Content;
-using Gee;
+ /* attribute.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private ArrayList<AttributeArgument> args = new ArrayList<AttributeArgument> ();
+
++using Valadoc.Content;
+
+ public class Valadoc.Api.Attribute : Item {
++ private Vala.ArrayList<AttributeArgument> args = new Vala.ArrayList<AttributeArgument> ();
+ private SourceFile file;
+
+ public string name {
+ private set;
+ get;
+ }
+
+ public Attribute (Node parent, SourceFile file, string name, void* data) {
+ base (data);
+
+ this.parent = parent;
+ this.name = name;
+ this.file = file;
+ }
+
+ public AttributeArgument? get_argument (string name) {
+ if (args != null) {
+ foreach (AttributeArgument arg in args) {
+ if (arg.name == name) {
+ return arg;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public AttributeArgument add_boolean (string name, bool value, void* data = null) {
+ AttributeArgument arg = new AttributeArgument.boolean (this, file, name, value, data);
+ args.add (arg);
+ return arg;
+ }
+
+ public AttributeArgument add_integer (string name, int value, void* data = null) {
+ AttributeArgument arg = new AttributeArgument.integer (this, file, name, value, data);
+ args.add (arg);
+ return arg;
+ }
+
+ public AttributeArgument add_double (string name, double value, void* data = null) {
+ AttributeArgument arg = new AttributeArgument.double (this, file, name, value, data);
+ args.add (arg);
+ return arg;
+ }
+
+ public AttributeArgument add_string (string name, string value, void* data = null) {
+ AttributeArgument arg = new AttributeArgument.string (this, file, name, value, data);
+ args.add (arg);
+ return arg;
+ }
+
+ public SourceFile get_source_file () {
+ return file;
+ }
+
+ protected override Inline build_signature () {
+ SignatureBuilder builder = new SignatureBuilder ();
+
+ builder.append_attribute ("[");
+ builder.append_type_name (name);
+
+ if (args.size > 0) {
+ builder.append_attribute ("(");
+ bool first = true;
+
+ foreach (AttributeArgument arg in args) {
+ if (first == false) {
+ builder.append_attribute (", ");
+ }
+ builder.append_content (arg.signature);
+ first = false;
+ }
+ builder.append_attribute (")");
+ }
+
+ builder.append_attribute ("]");
+
+ return builder.get ();
+ }
+ }
+
--- /dev/null
-using Gee;
-
-
+ /* attributeargument.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Content;
+
+ public class Valadoc.Api.AttributeArgument : Item {
+ public enum Type {
+ BOOLEAN,
+ INTEGER,
+ DOUBLE,
+ STRING
+ }
+
+ private SourceFile file;
+
+ public string name {
+ private set;
+ get;
+ }
+
+ public AttributeArgument.Type argument_type {
+ private set;
+ get;
+ }
+
+ public string value {
+ private set;
+ get;
+ }
+
+ public AttributeArgument.boolean (Attribute parent, SourceFile file, string name, bool value, void* data) {
+ this (parent, file, name, Type.BOOLEAN, value.to_string (), data);
+ }
+
+ public AttributeArgument.integer (Attribute parent, SourceFile file, string name, int value, void* data) {
+ this (parent, file, name, Type.INTEGER, value.to_string (), data);
+ }
+
+ public AttributeArgument.double (Attribute parent, SourceFile file, string name, double value, void* data) {
+ this (parent, file, name, Type.DOUBLE, value.to_string (), data);
+ }
+
+ public AttributeArgument.string (Attribute parent, SourceFile file, string name, string value, void* data) {
+ this (parent, file, name, Type.STRING, value, data);
+ }
+
+ private AttributeArgument (Attribute parent, SourceFile file, string name, Type type, string value, void* data) {
+ base (data);
+
+ this.argument_type = type;
+ this.parent = parent;
+ this.value = value;
+ this.file = file;
+ this.name = name;
+ }
+
+ public SourceFile get_source_file () {
+ return file;
+ }
+
+ public bool get_value_as_boolean () {
+ assert (argument_type == Type.BOOLEAN);
+
+ bool tmp;
+
+ if (bool.try_parse (value, out tmp)) {
+ return tmp;
+ }
+
+ assert_not_reached ();
+ }
+
+ public int get_value_as_integer () {
+ assert (argument_type == Type.INTEGER);
+
+ double tmp;
+
+ if (global::double.try_parse (value, out tmp) && tmp >= int.MIN && tmp <= int.MAX) {
+ return (int) tmp;
+ }
+
+ assert_not_reached ();
+ }
+
+ public double get_value_as_double () {
+ assert (argument_type == Type.DOUBLE);
+
+ double tmp;
+
+ if (global::double.try_parse (value, out tmp)) {
+ return tmp;
+ }
+
+ assert_not_reached ();
+ }
+
+ public string get_value_as_string () {
+ assert (argument_type == Type.STRING);
+
+ return value;
+ }
+
+ protected override Inline build_signature () {
+ SignatureBuilder builder = new SignatureBuilder ();
+
+ builder.append_attribute (name);
+ builder.append_attribute ("=");
+ builder.append_literal (value);
+
+ return builder.get ();
+ }
+ }
--- /dev/null
-using Gee;
-
+ /* browsable.vala
+ *
+ * Copyright (C) 2008 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ /**
+ * Specifies whether users are able to browse the item.
+ */
+ public interface Valadoc.Api.Browsable : Item {
+
+ /**
+ * Specifies whether users are able to browse the item.
+ */
+ public abstract bool is_browsable (Settings settings);
+ }
--- /dev/null
-using GLib;
-using Gee;
-
+ /* callable.vala
+ *
+ * Copyright (C) 2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc;
+
+ /**
+ * Used to translate imported C-documentation
+ */
+ public interface Valadoc.Api.Callable : Symbol {
+ /**
+ * The return type of this symbol.
+ *
+ * @return The return type of this symbol or null for void
+ */
+ public abstract TypeReference? return_type {
+ set;
+ get;
+ }
+
+ /**
+ * Used to avoid warnings for implicit parameters
+ */
+ internal abstract string? implicit_array_length_cparameter_name {
+ get;
+ set;
+ }
+ }
+
--- /dev/null
-using Valadoc.Api;
-using Gee;
+ /* childsymbolregistrar.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+
++using Valadoc.Api;
+
+ public class Valadoc.Api.ChildSymbolRegistrar : Visitor {
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_tree (Api.Tree item) {
+ item.accept_children (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_package (Package item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_namespace (Namespace item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_interface (Interface item) {
- Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
++ Vala.Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+ foreach (var type_ref in interfaces) {
+ ((Interface) type_ref.data_type).register_related_interface (item);
+ }
+
+ if (item.base_type != null) {
+ ((Class) item.base_type.data_type).register_derived_interface (item);
+ }
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_class (Class item) {
++ Vala.Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+ foreach (TypeReference type_ref in interfaces) {
+ ((Interface) type_ref.data_type).register_implementation (item);
+ }
+
+ if (item.base_type != null) {
+ ((Class) item.base_type.data_type).register_child_class (item);
+ }
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_struct (Struct item) {
+ if (item.base_type != null) {
+ ((Struct) item.base_type.data_type).register_child_struct (item);
+ }
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_property (Property item) {
+ item.accept_all_children (this, false);
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* class.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private ArrayList<TypeReference> interfaces;
+
++using Valadoc.Content;
+
+ /**
+ * Represents a class declaration.
+ */
+ public class Valadoc.Api.Class : TypeSymbol {
- this.interfaces = new ArrayList<TypeReference> ();
++ private Vala.ArrayList<TypeReference> interfaces;
+
+ private string? dbus_name;
+ private string? take_value_function_cname;
+ private string? get_value_function_cname;
+ private string? set_value_function_cname;
+ private string? unref_function_name;
+ private string? ref_function_name;
+ private string? free_function_name;
+ private string? finalize_function_name;
+ private string? param_spec_function_name;
+ private string? type_id;
+ private string? is_class_type_macro_name;
+ private string? class_type_macro_name;
+ private string? class_macro_name;
+ private string? private_cname;
+ private string? cname;
+
+ public Class (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, string? private_cname, string? class_macro_name,
+ string? type_macro_name, string? is_type_macro_name, string? type_cast_macro_name,
+ string? type_function_name, string? class_type_macro_name, string? is_class_type_macro_name,
+ string? dbus_name, string? type_id, string? param_spec_function_name, string? ref_function_name,
+ string? unref_function_name, string? free_function_name, string? finalize_function_name,
+ string? take_value_function_cname, string? get_value_function_cname, string? set_value_function_cname,
+ bool is_fundamental, bool is_abstract, bool is_basic_type, void* data)
+ {
+ base (parent, file, name, accessibility, comment, type_macro_name,
+ is_type_macro_name, type_cast_macro_name, type_function_name, is_basic_type, data);
+
- public Collection<TypeReference> get_implemented_interface_list () {
++ this.interfaces = new Vala.ArrayList<TypeReference> ();
+
+ this.is_class_type_macro_name = is_class_type_macro_name;
+ this.class_type_macro_name = class_type_macro_name;
+ this.class_macro_name = class_macro_name;
+ this.private_cname = private_cname;
+ this.dbus_name = dbus_name;
+ this.type_id = type_id;
+ this.cname = cname;
+
+ this.param_spec_function_name = param_spec_function_name;
+
+ this.unref_function_name = unref_function_name;
+ this.ref_function_name = ref_function_name;
+ this.finalize_function_name = finalize_function_name;
+ this.free_function_name = free_function_name;
+
+ this.take_value_function_cname = take_value_function_cname;
+ this.get_value_function_cname = get_value_function_cname;
+ this.set_value_function_cname = set_value_function_cname;
+
+ this.is_fundamental = is_fundamental;
+ this.is_abstract = is_abstract;
+ }
+
+ /**
+ * Specifies the base class.
+ */
+ public TypeReference? base_type {
+ set;
+ get;
+ }
+
+ /**
+ * Returns the name of this class as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * Returns the name of this class' private data structure as it is used in C.
+ */
+ public string? get_private_cname () {
+ return private_cname;
+ }
+
+ /**
+ * Returns the C symbol representing the runtime type id for this data type.
+ */
+ public string? get_type_id () {
+ return type_id;
+ }
+
+ /**
+ * Returns the C function name that increments the reference count of
+ * instances of this data type.
+ *
+ * @return the name of the C function or null if this data type does not
+ * support reference counting
+ */
+ public string? get_ref_function_cname () {
+ return ref_function_name;
+ }
+
+ /**
+ * Returns the C function name that decrements the reference count of
+ * instances of this data type.
+ *
+ * @return the name of the C function or null if this data type does not
+ * support reference counting
+ */
+ public string? get_unref_function_cname () {
+ return unref_function_name;
+ }
+
+ /**
+ * Returns the C function name that frees the
+ * instances of this data type.
+ *
+ * @return the name of the C function or null
+ */
+ public string? get_free_function_name () {
+ return free_function_name;
+ }
+
+ /**
+ * Returns the C function name that finalizes the
+ * instances of this data type.
+ *
+ * @return the name of the C function or null
+ */
+ public string? get_finalize_function_name () {
+ return finalize_function_name;
+ }
+
+ /**
+ * Returns the cname of the GValue parameter spec function.
+ */
+ public string? get_param_spec_function_cname () {
+ return param_spec_function_name;
+ }
+
+ /**
+ * Returns the cname of the GValue setter function.
+ */
+ public string? get_set_value_function_cname () {
+ return set_value_function_cname;
+ }
+
+ /**
+ * Returns the cname of the GValue getter function.
+ */
+ public string? get_get_value_function_cname () {
+ return get_value_function_cname;
+ }
+
+ /**
+ * Returns the cname of the GValue taker function.
+ */
+ public string? get_take_value_function_cname () {
+ return take_value_function_cname;
+ }
+
+ /**
+ * Returns the dbus-name.
+ */
+ public string? get_dbus_name () {
+ return dbus_name;
+ }
+
+ /**
+ * Gets the name of the GType macro which returns the class struct.
+ */
+ public string get_class_macro_name () {
+ return class_macro_name;
+ }
+
+ /**
+ * Gets the name of the GType macro which returns the type of the class.
+ */
+ public string get_class_type_macro_name () {
+ return class_type_macro_name;
+ }
+
+ /**
+ * Gets the name of the GType macro which returns whether a class instance is of a given type.
+ */
+ public string get_is_class_type_macro_name () {
+ return is_class_type_macro_name;
+ }
+
+ /**
+ * Returns a list of all newly implemented interfaces.
+ *
+ * @see get_full_implemented_interface_list
+ */
- private Collection<TypeReference> _full_implemented_interfaces = null;
++ public Vala.Collection<TypeReference> get_implemented_interface_list () {
+ return this.interfaces;
+ }
+
- public Collection<TypeReference> get_full_implemented_interface_list () {
++ private Vala.Collection<TypeReference> _full_implemented_interfaces = null;
+
+ /**
+ * Returns a list of all implemented interfaces.
+ *
+ * @see get_implemented_interface_list
+ */
- _full_implemented_interfaces = new LinkedList<TypeReference> ();
++ public Vala.Collection<TypeReference> get_full_implemented_interface_list () {
+ if (_full_implemented_interfaces == null) {
- private Set<Interface> _known_derived_interfaces = new TreeSet<Interface> ();
- private Set<Class> _known_child_classes = new TreeSet<Class> ();
++ _full_implemented_interfaces = new Vala.ArrayList<TypeReference> ();
+ _full_implemented_interfaces.add_all (this.interfaces);
+
+ if (base_type != null) {
+ _full_implemented_interfaces.add_all (((Class) base_type.data_type).get_full_implemented_interface_list ());
+ }
+ }
+
+ return _full_implemented_interfaces;
+ }
+
+ public void add_interface (TypeReference iface) {
+ interfaces.add (iface);
+ }
+
+ /**
+ * Specifies whether this class is abstract.
+ */
+ public bool is_abstract {
+ private set;
+ get;
+ }
+
+ /**
+ * Specifies whether this class is fundamental.
+ */
+ public bool is_fundamental {
+ private set;
+ get;
+ }
+
+ public bool is_compact {
+ get {
+ return base_type == null && get_attribute ("Compact") != null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type { get { return NodeType.CLASS; } }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_class (this);
+ }
+
- public Collection<Class> get_known_child_classes () {
- return _known_child_classes.read_only_view;
++ private Vala.Set<Interface> _known_derived_interfaces = new Vala.HashSet<Interface> ();
++ private Vala.Set<Class> _known_child_classes = new Vala.HashSet<Class> ();
+
+ /**
+ * Returns a list of all known classes based on this class
+ */
- public Collection<Interface> get_known_derived_interfaces () {
- return _known_derived_interfaces.read_only_view;
++ public Vala.Collection<Class> get_known_child_classes () {
++ return _known_child_classes;
+ }
+
+ /**
+ * Returns a list of all known interfaces based on this class
+ */
++ public Vala.Collection<Interface> get_known_derived_interfaces () {
++ return _known_derived_interfaces;
+ }
+
+ public void register_derived_interface (Interface iface) {
+ _known_derived_interfaces.add (iface);
+ }
+
+ public void register_child_class (Class cl) {
+ if (this.base_type != null) {
+ ((Class) this.base_type.data_type).register_child_class (cl);
+ }
+
+ _known_child_classes.add (cl);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ signature.append_keyword (accessibility.to_string ());
+ if (is_abstract) {
+ signature.append_keyword ("abstract");
+ }
+ signature.append_keyword ("class");
+ signature.append_symbol (this);
+
+ var type_parameters = get_children_by_type (NodeType.TYPE_PARAMETER, false);
+ if (type_parameters.size > 0) {
+ signature.append ("<", false);
+ bool first = true;
+ foreach (Item param in type_parameters) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, false);
+ first = false;
+ }
+ signature.append (">", false);
+ }
+
+ bool first = true;
+ if (base_type != null) {
+ signature.append (":");
+
+ signature.append_content (base_type.signature);
+ first = false;
+ }
+
+ if (interfaces.size > 0) {
+ if (first) {
+ signature.append (":");
+ }
+
+ foreach (Item implemented_interface in interfaces) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (implemented_interface.signature);
+ first = false;
+ }
+ }
+
+ return signature.get ();
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* constant.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
++
+ using Valadoc.Content;
+
+ /**
+ * Represents a type member with a constant value.
+ */
+ public class Valadoc.Api.Constant : Member {
+ private string? cname;
+
+ /**
+ * The data type of this constant.
+ */
+ public TypeReference constant_type {
+ set;
+ get;
+ }
+
+ public Constant (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, void* data)
+ {
+ base (parent, file, name, accessibility, comment, data);
+
+ this.cname = cname;
+ }
+
+ /**
+ * Returns the name of this constant as it is used in C.
+ */
+ public string get_cname () {
+ return cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ return new SignatureBuilder ()
+ .append_keyword (accessibility.to_string ())
+ .append_keyword ("const")
+ .append_content (constant_type.signature)
+ .append_symbol (this)
+ .get ();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.CONSTANT; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_constant (this);
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* delegate.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
++
+ using Valadoc.Content;
+
+
+ /**
+ * Represents a Delegate.
+ */
+ public class Valadoc.Api.Delegate : TypeSymbol, Callable {
+ private string? cname;
+
+ /**
+ * {@inheritDoc}
+ */
+ internal string? implicit_array_length_cparameter_name {
+ get;
+ set;
+ }
+
+
+ public Delegate (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, bool is_static, void* data)
+ {
+ base (parent, file, name, accessibility, comment, null, null, null, null, false, data);
+
+ this.is_static = is_static;
+ this.cname = cname;
+ }
+
+ /**
+ * Returns the name of this delegate as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public TypeReference? return_type {
+ set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.DELEGATE; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_delegate (this);
+ }
+
+ /**
+ * Specifies whether this delegate is static
+ */
+ public bool is_static {
+ private set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ signature.append_keyword (accessibility.to_string ());
+ signature.append_keyword ("delegate");
+ signature.append_content (return_type.signature);
+ signature.append_symbol (this);
+
+ var type_parameters = get_children_by_type (NodeType.TYPE_PARAMETER);
+ if (type_parameters.size > 0) {
+ signature.append ("<", false);
+ bool first = true;
+ foreach (Item param in type_parameters) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, false);
+ first = false;
+ }
+ signature.append (">", false);
+ }
+
+ signature.append ("(");
+
+ bool first = true;
+ foreach (Node param in get_children_by_type (NodeType.FORMAL_PARAMETER, false)) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, !first);
+ first = false;
+ }
+
+ signature.append (")", false);
+
+ var exceptions = get_children_by_types ({NodeType.ERROR_DOMAIN, NodeType.CLASS});
+ if (exceptions.size > 0) {
+ signature.append_keyword ("throws");
+ first = true;
+ foreach (Node param in exceptions) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_type (param);
+ first = false;
+ }
+ }
+
+ return signature.get ();
+ }
+ }
+
--- /dev/null
-using Valadoc.Api;
-using Gee;
+ /* driver.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Api;
+
+ /**
+ * A plugin register function for drivers
+ *
+ * @see ModuleLoader
+ */
+ [CCode (has_target = false)]
+ public delegate Type Valadoc.DriverRegisterFunction (ModuleLoader module_loader);
+
+
+
+ public interface Valadoc.Driver : Object {
+ public abstract void write_gir (Settings settings, ErrorReporter reporter);
+
+ public abstract Api.Tree? build (Settings settings, ErrorReporter reporter);
+ }
+
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* enum.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents an enum declaration.
+ */
+ public class Valadoc.Api.Enum : TypeSymbol {
+ private string cname;
+
+ public Enum (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, string? type_macro_name,
+ string? type_function_name, void* data)
+ {
+ base (parent, file, name, accessibility, comment, type_macro_name, null, null,
+ type_function_name, false, data);
+ this.cname = cname;
+ }
+
+ /**
+ * Returns the name of this enum as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type { get { return NodeType.ENUM; } }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_enum (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ return new SignatureBuilder ()
+ .append_keyword (accessibility.to_string ())
+ .append_keyword ("enum")
+ .append_symbol (this)
+ .get ();
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* enumvalue.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents an enum member.
+ */
+ public class Valadoc.Api.EnumValue: Symbol {
+ private SourceComment? source_comment;
+ private string? cname;
+
+ public Content.Run default_value {
+ get;
+ set;
+ }
+
+ /**
+ * Specifies whether the parameter has a default value
+ */
+ public bool has_default_value {
+ get {
+ return default_value != null;
+ }
+ }
+
+ public EnumValue (Enum parent, SourceFile file, string name, SourceComment? comment, string? cname, void* data) {
+ base (parent, file, name, parent.accessibility, data);
+
+ this.source_comment = comment;
+ this.cname = cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void parse_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ return ;
+ }
+
+ if (source_comment != null) {
+ documentation = parser.parse (this, source_comment);
+ }
+
+ base.parse_comments (settings, parser);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void check_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ parser.check (this, documentation);
+ }
+
+ base.check_comments (settings, parser);
+ }
+
+ /**
+ * Returns the name of this enum value as it is used in C.
+ */
+ public string get_cname () {
+ return cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type { get { return NodeType.ENUM_VALUE; } }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_enum_value (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var builder = new SignatureBuilder ()
+ .append_symbol (this);
+
+ if (has_default_value) {
+ builder.append ("=");
+ builder.append_content (default_value);
+ }
+
+ return builder.get ();
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* errorcode.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents an errordomain member in the source code.
+ */
+ public class Valadoc.Api.ErrorCode : Symbol {
+ private SourceComment? source_comment;
+ private string? dbus_name;
+ private string? cname;
+
+ public ErrorCode (ErrorDomain parent, SourceFile file, string name, SourceComment? comment,
+ string? cname, string? dbus_name, void* data)
+ {
+ base (parent, file, name, parent.accessibility, data);
+
+ this.source_comment = comment;
+ this.dbus_name = dbus_name;
+ this.cname = cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void parse_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ return ;
+ }
+
+ if (source_comment != null) {
+ documentation = parser.parse (this, source_comment);
+ }
+
+ base.parse_comments (settings, parser);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void check_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ parser.check (this, documentation);
+ }
+
+ base.check_comments (settings, parser);
+ }
+
+ /**
+ * Returns the name of this class as it is used in C.
+ */
+ public string get_cname () {
+ return cname;
+ }
+
+ /**
+ * Returns the dbus-name.
+ */
+ public string get_dbus_name () {
+ return dbus_name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.ERROR_CODE; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_error_code (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ return new SignatureBuilder ()
+ .append_symbol (this)
+ .get ();
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* errordomain.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents an error domain declaration.
+ */
+ public class Valadoc.Api.ErrorDomain : TypeSymbol {
+ private string? quark_function_name;
+ private string? quark_macro_name;
+ private string? dbus_name;
+ private string? cname;
+
+ public ErrorDomain (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, string? quark_macro_name,
+ string? quark_function_name, string? dbus_name, void* data)
+ {
+ base (parent, file, name, accessibility, comment, null, null, null, null, false, data);
+
+ this.quark_function_name = quark_function_name;
+ this.quark_macro_name = quark_macro_name;
+ this.dbus_name = dbus_name;
+ this.cname = cname;
+ }
+
+ /**
+ * Returns the name of this errordomain as it is used in C.
+ */
+ public string? get_cname () {
+ return this.cname;
+ }
+
+ /**
+ * Returns the dbus-name.
+ */
+ public string? get_dbus_name () {
+ return dbus_name;
+ }
+
+ /**
+ * Gets the name of the quark() function which represents the error domain
+ */
+ public string get_quark_function_name () {
+ return quark_function_name;
+ }
+
+ /**
+ * Gets the name of the quark macro which represents the error domain
+ */
+ public string get_quark_macro_name () {
+ return quark_macro_name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.ERROR_DOMAIN; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_error_domain (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ return new SignatureBuilder ()
+ .append_keyword (accessibility.to_string ())
+ .append_keyword ("errordomain")
+ .append_symbol (this)
+ .get ();
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* field.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents a field.
+ */
+ public class Valadoc.Api.Field : Member {
+ private string? cname;
+
+ public Field (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, bool is_static, bool is_volatile,
+ void* data)
+ {
+ base (parent, file, name, accessibility, comment, data);
+
+ this.is_static = !(parent is Namespace) && is_static;
+ this.is_volatile = is_volatile;
+
+ this.cname = cname;
+ }
+
+ /**
+ * Returns the name of this field as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * The field type.
+ *
+ * @return The field type or null for void
+ */
+ public TypeReference? field_type {
+ set;
+ get;
+ }
+
+ /**
+ * Specifies whether the field is static.
+ */
+ public bool is_static {
+ private set;
+ get;
+ }
+
+ /**
+ * Specifies whether the field is volatile.
+ */
+ public bool is_volatile {
+ private set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ signature.append_keyword (accessibility.to_string ());
+ if (is_static) {
+ signature.append_keyword ("static");
+ }
+ if (is_volatile) {
+ signature.append_keyword ("volatile");
+ }
+
+ signature.append_content (field_type.signature);
+ signature.append_symbol (this);
+ return signature.get ();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.FIELD; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_field (this);
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* formalparameter.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
++
+ using Valadoc.Content;
+
+ /**
+ * Represents a formal parameter in method, signal and delegate signatures.
+ */
+ public class Valadoc.Api.FormalParameter : Symbol {
+ public Content.Run default_value {
+ get;
+ set;
+ }
+
+ /**
+ * Used to translate imported C-documentation
+ */
+ internal string? implicit_array_length_cparameter_name {
+ get;
+ set;
+ }
+
+ /**
+ * Used to translate imported C-documentation
+ */
+ internal string? implicit_closure_cparameter_name {
+ get;
+ set;
+ }
+
+ /**
+ * Used to translate imported C-documentation
+ */
+ internal string? implicit_destroy_cparameter_name {
+ get;
+ set;
+ }
+
+ private FormalParameterType type;
+
+ public FormalParameter (Node parent, SourceFile file, string? name, SymbolAccessibility accessibility, FormalParameterType type, bool ellipsis, void* data) {
+ base (parent, file, name, accessibility, data);
+ assert ((name == null && ellipsis) || (name != null && !ellipsis));
+
+ this.ellipsis = ellipsis;
+ this.type = type;
+ }
+
+ /**
+ * Specifies whether the parameter direction is out
+ */
+ public bool is_out {
+ get {
+ return type == FormalParameterType.OUT;
+ }
+ }
+
+ /**
+ * Specifies whether the parameter direction is ref
+ */
+ public bool is_ref {
+ get {
+ return type == FormalParameterType.REF;
+ }
+ }
+
+ /**
+ * Specifies whether the parameter has a default value
+ */
+ public bool has_default_value {
+ get {
+ return default_value != null;
+ }
+ }
+
+ /**
+ * The parameter type.
+ *
+ * @return The parameter type or null for void
+ */
+ public TypeReference? parameter_type {
+ set;
+ get;
+ }
+
+ /**
+ * Specifies whether the methods accepts a variable number of arguments
+ */
+ public bool ellipsis {
+ private set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.FORMAL_PARAMETER; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_formal_parameter (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ if (ellipsis) {
+ signature.append ("...");
+ } else {
+ if (is_out) {
+ signature.append_keyword ("out");
+ } else if (is_ref) {
+ signature.append_keyword ("ref");
+ }
+
+ signature.append_content (parameter_type.signature);
+ signature.append (name);
+
+ if (has_default_value) {
+ signature.append ("=");
+ signature.append_content (default_value);
+ }
+ }
+
+ return signature.get ();
+ }
+ }
+
--- /dev/null
-using Gee;
-
-
+ /* sourcecomment.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
- private Map<string, SourceComment> parameters = new HashMap<string, SourceComment> ();
+ /**
+ * A documentation comment used by valadoc
+ */
+ public class Valadoc.Api.GirSourceComment : SourceComment {
- public MapIterator<string, SourceComment> parameter_iterator () {
++ private Vala.Map<string, SourceComment> parameters = new Vala.HashMap<string, SourceComment> (str_hash, str_equal);
+
+ public string? instance_param_name { set; get; }
+ public SourceComment? return_comment { set; get; }
+ public SourceComment? deprecated_comment { set; get; }
+ public SourceComment? version_comment { get; set; }
+ public SourceComment? stability_comment { get; set; }
+
+
++ public Vala.MapIterator<string, SourceComment> parameter_iterator () {
+ return parameters.map_iterator ();
+ }
+
+ public void add_parameter_content (string param_name, SourceComment comment) {
+ this.parameters.set (param_name, comment);
+ }
+
+ public SourceComment? get_parameter_comment (string param_name) {
+ if (parameters == null) {
+ return null;
+ }
+
+ return parameters.get (param_name);
+ }
+
+ public GirSourceComment (string content, SourceFile file, int first_line, int first_column, int last_line, int last_column) {
+ base (content, file, first_line, first_column, last_line, last_column);
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
-
+ /* interface.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private ArrayList<TypeReference> interfaces = new ArrayList<TypeReference> ();
+
++using Valadoc.Content;
+
+ /**
+ * Represents a interface declaration in the source code.
+ */
+ public class Valadoc.Api.Interface : TypeSymbol {
+ private string? interface_macro_name;
+ private string? dbus_name;
+ private string? cname;
+
+
+ public Interface (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, string? type_macro_name, string? is_type_macro_name,
+ string? type_cast_macro_name, string? type_function_name, string interface_macro_name,
+ string? dbus_name, void* data)
+ {
+ base (parent, file, name, accessibility, comment, type_macro_name, is_type_macro_name,
+ type_cast_macro_name, type_function_name, false, data);
+
+ this.interface_macro_name = interface_macro_name;
+ this.dbus_name = dbus_name;
+ this.cname = cname;
+ }
+
+ /**
+ * A list of preconditioned interfaces
+ */
- public Collection<TypeReference> get_implemented_interface_list () {
++ private Vala.ArrayList<TypeReference> interfaces = new Vala.ArrayList<TypeReference> ();
+
+ /**
+ * Add a newpreconditioned interface to the list
+ */
+ public void add_interface (TypeReference iface) {
+ interfaces.add (iface);
+ }
+
+ /**
+ * Returns a list of newly preconditioned interfaces
+ */
- private Collection<TypeReference> _full_implemented_interfaces = null;
++ public Vala.Collection<TypeReference> get_implemented_interface_list () {
+ return this.interfaces;
+ }
+
+
+ /**
+ * A list of all preconditioned interfaces
+ */
- public Collection<TypeReference> get_full_implemented_interface_list () {
++ private Vala.Collection<TypeReference> _full_implemented_interfaces = null;
+
+ /**
+ * Returns a list of all preconditioned interfaces
+ */
- _full_implemented_interfaces = new LinkedList<TypeReference> ();
++ public Vala.Collection<TypeReference> get_full_implemented_interface_list () {
+ if (_full_implemented_interfaces == null) {
- private Set<Interface> _known_related_interfaces = new TreeSet<Interface> ();
++ _full_implemented_interfaces = new Vala.ArrayList<TypeReference> ();
+ _full_implemented_interfaces.add_all (this.interfaces);
+
+ if (base_type != null) {
+ _full_implemented_interfaces.add_all (((Class) base_type.data_type).get_full_implemented_interface_list ());
+ }
+ }
+
+ return _full_implemented_interfaces;
+ }
+
+ /**
+ * Returns the name of this interface as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * Returns the dbus-name.
+ */
+ public string? get_dbus_name () {
+ return dbus_name;
+ }
+
+ /**
+ * Gets the name of the GType macro which returns the interface struct.
+ */
+ public string get_interface_macro_name () {
+ return interface_macro_name;
+ }
+
+ /**
+ * A preconditioned class or null
+ */
+ public TypeReference? base_type {
+ set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.INTERFACE; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_interface (this);
+ }
+
+ /**
+ * A list of all known related (sub-)interfaces
+ */
- private Set<Class> _known_implementations = new TreeSet<Class> ();
++ private Vala.Set<Interface> _known_related_interfaces = new Vala.HashSet<Interface> ();
+
+ /**
+ * A list of all known implementations of this interface
+ */
- public Collection<Class> get_known_implementations () {
++ private Vala.Set<Class> _known_implementations = new Vala.HashSet<Class> ();
+
+ /**
+ * Returns a list of all known implementations of this interface
+ */
- public Collection<Interface> get_known_related_interfaces () {
++ public Vala.Collection<Class> get_known_implementations () {
+ return _known_implementations;
+ }
+
+ /**
+ * Returns a list of all known related (sub-)interfaces
+ */
++ public Vala.Collection<Interface> get_known_related_interfaces () {
+ return _known_related_interfaces;
+ }
+
+ public void register_related_interface (Interface iface) {
+ _known_related_interfaces.add (iface);
+ }
+
+ public void register_implementation (Class cl) {
+ _known_implementations.add (cl);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ signature.append_keyword (accessibility.to_string ());
+ signature.append_keyword ("interface");
+ signature.append_symbol (this);
+
+ var type_parameters = get_children_by_type (NodeType.TYPE_PARAMETER, false);
+ if (type_parameters.size > 0) {
+ signature.append ("<", false);
+ bool first = true;
+ foreach (Item param in type_parameters) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, false);
+ first = false;
+ }
+ signature.append (">", false);
+ }
+
+ bool first = true;
+ if (base_type != null) {
+ signature.append (":");
+
+ signature.append_content (base_type.signature);
+ first = false;
+ }
+
+ if (interfaces.size > 0) {
+ if (first) {
+ signature.append (":");
+ }
+
+ foreach (Item implemented_interface in interfaces) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (implemented_interface.signature);
+ first = false;
+ }
+ }
+
+ return signature.get ();
+ }
+ }
+
--- /dev/null
-using Valadoc.Content;
-using Gee;
+ /* item.vala
+ *
+ * Copyright (C) 2008 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents a node in the api tree.
+ */
+ public abstract class Valadoc.Api.Item : Object {
+ private Inline _signature;
+
+ public void* data {
+ private set;
+ get;
+ }
+
+ /**
+ * The parent of this item.
+ */
+ public Item parent {
+ protected set;
+ get;
+ }
+
+ public Item (void* data) {
+ this.data = data;
+ }
+
+ internal virtual void parse_comments (Settings settings, DocumentationParser parser) {
+ }
+
+ internal virtual void check_comments (Settings settings, DocumentationParser parser) {
+ }
+
+
+ /**
+ * The signature of this item.
+ */
+ public Inline signature {
+ get {
+ if (_signature == null) {
+ _signature = build_signature ();
+ }
+ return _signature;
+ }
+ }
+
+ protected abstract Inline build_signature ();
+ }
+
--- /dev/null
-using Gee;
+ /* member.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public abstract class Valadoc.Api.Member : Symbol {
+ private SourceComment? source_comment;
+
+ public Member (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, void* data)
+ {
+ base (parent, file, name, accessibility, data);
+
+ this.source_comment = comment;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void parse_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ return ;
+ }
+
+ if (source_comment != null) {
+ documentation = parser.parse (this, source_comment);
+ }
+
+ base.parse_comments (settings, parser);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void check_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ parser.check (this, documentation);
+ }
+
+ base.check_comments (settings, parser);
+ }
+ }
--- /dev/null
-using Valadoc.Content;
-using Gee;
+ /* method.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents a function or a method.
+ */
+ public class Valadoc.Api.Method : Member, Callable {
+ private string? finish_function_cname;
+ private string? dbus_result_name;
+ private string? dbus_name;
+ private string? cname;
+
+ private MethodBindingType binding_type;
+
+ /**
+ * {@inheritDoc}
+ */
+ internal string? implicit_array_length_cparameter_name {
+ get;
+ set;
+ }
+
+
+ public Method (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, string? dbus_name, string? dbus_result_name,
+ string? finish_function_cname, MethodBindingType binding_type, bool is_yields,
+ bool is_dbus_visible, bool is_constructor, void* data)
+ {
+ base (parent, file, name, accessibility, comment, data);
+
+ this.finish_function_cname = finish_function_cname;
+ this.dbus_result_name = dbus_result_name;
+ this.dbus_name = dbus_name;
+ this.cname = cname;
+
+ this.binding_type = binding_type;
+ this.is_dbus_visible = is_dbus_visible;
+ this.is_constructor = is_constructor;
+ this.is_yields = is_yields;
+ }
+
+ /**
+ * Returns the name of this method as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * Returns the name of the finish function as it is used in C.
+ */
+ public string? get_finish_function_cname () {
+ return finish_function_cname;
+ }
+
+ /**
+ * Returns the dbus-name.
+ */
+ public string get_dbus_name () {
+ return dbus_name;
+ }
+
+ public string get_dbus_result_name () {
+ return dbus_result_name;
+ }
+
+ /**
+ * Specifies the virtual or abstract method this method overrides.
+ */
+ public weak Method? base_method {
+ set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public TypeReference? return_type {
+ set;
+ get;
+ }
+
+ /**
+ * Specifies whether this method is asynchronous
+ */
+ public bool is_yields {
+ private set;
+ get;
+ }
+
+ /**
+ * Specifies whether this method is abstract
+ */
+ public bool is_abstract {
+ get {
+ return binding_type == MethodBindingType.ABSTRACT;
+ }
+ }
+
+ /**
+ * Specifies whether this method is virtual
+ */
+ public bool is_virtual {
+ get {
+ return binding_type == MethodBindingType.VIRTUAL;
+ }
+ }
+
+ /**
+ * Specifies whether this method overrides another one
+ */
+ public bool is_override {
+ get {
+ return binding_type == MethodBindingType.OVERRIDE;
+ }
+ }
+
+ /**
+ * Specifies whether this method is static
+ */
+ public bool is_static {
+ get {
+ return !is_constructor && binding_type == MethodBindingType.STATIC
+ && parent is Namespace == false;
+ }
+ }
+
+ /**
+ * Specifies whether this method is a creation method
+ */
+ public bool is_constructor {
+ private set;
+ get;
+ }
+
+ /**
+ * Specifies whether this method is inline
+ */
+ public bool is_inline {
+ get {
+ return binding_type == MethodBindingType.INLINE;
+ }
+ }
+
+ /**
+ * Specifies whether this method is visible for dbus
+ */
+ public bool is_dbus_visible {
+ private set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ signature.append_keyword (accessibility.to_string ());
+
+ if (!is_constructor) {
+ if (is_static) {
+ signature.append_keyword ("static");
+ } else if (is_abstract) {
+ signature.append_keyword ("abstract");
+ } else if (is_override) {
+ signature.append_keyword ("override");
+ } else if (is_virtual) {
+ signature.append_keyword ("virtual");
+ }
+ if (is_inline) {
+ signature.append_keyword ("inline");
+ }
+ if (is_yields) {
+ signature.append_keyword ("async");
+ }
+
+ signature.append_content (return_type.signature);
+ }
+
+ signature.append_symbol (this);
+
+ var type_parameters = get_children_by_type (NodeType.TYPE_PARAMETER, false);
+ if (type_parameters.size > 0) {
+ signature.append ("<", false);
+ bool first = true;
+ foreach (Item param in type_parameters) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, false);
+ first = false;
+ }
+ signature.append (">", false);
+ }
+
+ signature.append ("(");
+
+ bool first = true;
+ foreach (Node param in get_children_by_type (NodeType.FORMAL_PARAMETER, false)) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, !first);
+ first = false;
+ }
+
+ signature.append (")", false);
+
+ var exceptions = get_children_by_types ({NodeType.ERROR_DOMAIN, NodeType.CLASS});
+ if (exceptions.size > 0) {
+ signature.append_keyword ("throws");
+ first = true;
+ foreach (Node param in exceptions) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_type (param);
+ first = false;
+ }
+ }
+
+ return signature.get ();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get {
+ return is_constructor ? NodeType.CREATION_METHOD :
+ is_static ? NodeType.STATIC_METHOD : NodeType.METHOD;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_method (this);
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* namespace.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents a namespace declaration.
+ */
+ public class Valadoc.Api.Namespace : Symbol {
+ private SourceComment? source_comment;
+
+ public Namespace (Api.Node parent, SourceFile file, string? name, SourceComment? comment, void* data) {
+ base (parent, file, name, SymbolAccessibility.PUBLIC, data);
+
+ this.source_comment = comment;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void parse_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ return ;
+ }
+
+ if (source_comment != null) {
+ documentation = parser.parse (this, source_comment);
+ }
+
+ base.parse_comments (settings, parser);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void check_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ parser.check (this, documentation);
+ }
+
+ base.check_comments (settings, parser);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ return new SignatureBuilder ()
+ .append_keyword (accessibility.to_string ())
+ .append_keyword ("namespace")
+ .append_symbol (this)
+ .get ();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type { get { return NodeType.NAMESPACE; } }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_namespace (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override bool is_browsable (Settings settings) {
+ return has_visible_children (settings);
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* node.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ * Copyright (C) 20011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
-public abstract class Valadoc.Api.Node : Item, Browsable, Documentation, Comparable<Node> {
+
+ /**
+ * Represents a node in the api tree.
+ */
- private Map<string, Node> per_name_children;
- private Map<NodeType, Gee.List<Node>> per_type_children;
++public abstract class Valadoc.Api.Node : Item, Browsable, Documentation {
+ protected bool do_document = false;
+ private SourceFile file;
+
+ /**
+ * The name of the node
+ */
+ public string? name {
+ private set;
+ get;
+ }
+
+ public SourceFile get_source_file () {
+ return file;
+ }
+
+ /**
+ * Returns the type of this node
+ */
+ public abstract NodeType node_type { get; }
+
- per_name_children = new HashMap<string, Node> ();
- per_type_children = new HashMap<NodeType, Gee.List<Node>> ();
++ private Vala.Map<string, Node> per_name_children;
++ private Vala.Map<NodeType, Vala.List<Node>> per_type_children;
+
+
+ public Node (Node? parent, SourceFile? file, string? name, void* data) {
+ base (data);
+
- Gee.List<Node> children = per_type_children.get (child.node_type);
++ per_name_children = new Vala.HashMap<string, Node> (str_hash, str_equal);
++ per_type_children = new Vala.HashMap<NodeType, Vala.List<Node>> ();
+
+ if (name != null && (is_keyword (name) || name[0].isdigit ())) {
+ this.name = "@" + name;
+ } else {
+ this.name = name;
+ }
+
+ this.parent = parent;
+ this.file = file;
+ }
+
+ /**
+ * Visits this node with the specified Visitor.
+ *
+ * @param visitor the visitor to be called while traversing
+ */
+ public abstract void accept (Visitor visitor);
+
+ /**
+ * {@inheritDoc}
+ */
+ // TODO: rename to is_visible
+ public abstract bool is_browsable (Settings settings);
+
+ /**
+ * {@inheritDoc}
+ */
+ public string? get_filename () {
+ if (file == null) {
+ return null;
+ }
+
+ return file.relative_path;
+ }
+
+ public void add_child (Symbol child) {
+ if (child.name != null) {
+ if (child.name[0] == '@') {
+ per_name_children.set (child.name.next_char (), child);
+ } else {
+ per_name_children.set (child.name, child);
+ }
+ } else {
+ // Special case for the root namespace
+ per_name_children.set ("", child);
+ }
+
- children = new ArrayList<Node> ();
++ Vala.List<Node> children = per_type_children.get (child.node_type);
+ if (children == null) {
- foreach (Node node in per_name_children.values) {
++ children = new Vala.ArrayList<Node> ();
+ per_type_children.set (child.node_type, children);
+ }
+
+ children.add (child);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void parse_comments (Settings settings, DocumentationParser parser) {
+ do_document = true;
+
- foreach (Node node in per_name_children.values) {
++ foreach (Node node in per_name_children.get_values ()) {
+ if (node.is_browsable (settings)) {
+ node.parse_comments (settings, parser);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void check_comments (Settings settings, DocumentationParser parser) {
+
- Gee.List<Node>? all_children = per_type_children.get (type);
++ foreach (Node node in per_name_children.get_values ()) {
+ if (node.is_browsable (settings)) {
+ node.check_comments (settings, parser);
+ }
+ }
+ }
+
+
+ /**
+ * Specifies whether this node has at least one visible child with the given type
+ *
+ * @param type a node type
+ */
+ public bool has_visible_children_by_type (NodeType type, Settings settings) {
- return has_visible_children_by_types (per_type_children.keys.to_array (), settings);
++ Vala.List<Node>? all_children = per_type_children.get (type);
+ if (all_children != null) {
+ foreach (Node node in all_children) {
+ if (node.is_browsable (settings)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Specifies whether this node has at least one visible child with the given types
+ *
+ * @param types a list of node types
+ */
+ public bool has_visible_children_by_types (NodeType[] types, Settings settings) {
+ foreach (NodeType type in types) {
+ if (has_visible_children_by_type (type, settings)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Specifies whether this node has at least one visible child
+ */
+ public bool has_visible_children (Settings settings) {
- Gee.List<Node>? all_children = per_type_children.get (type);
++ return has_visible_children_by_types (per_type_children.get_keys ().to_array (), settings);
+ }
+
+ /**
+ * Specifies whether this node has at least one child with the given type
+ *
+ * @param type a node type
+ */
+ public bool has_children_by_type (NodeType type) {
- public Gee.List<Node> get_children_by_type (NodeType type, bool filtered = true) {
- var children = new ArrayList<Node> ();
++ Vala.List<Node>? all_children = per_type_children.get (type);
+ return all_children != null && !all_children.is_empty;
+ }
+
+ /**
+ * Specifies whether this node has at least one child with the given types
+ *
+ * @param types a list of node types
+ */
+ public bool has_children (NodeType[] types) {
+ foreach (NodeType type in types) {
+ if (has_children_by_type (type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a list of all children with the given type.
+ *
+ * @param type a node type
+ * @param filtered specifies whether nodes which are not browsable should appear in the list
+ */
- Gee.List<Node> all_children = per_type_children.get (type);
++ public Vala.List<Node> get_children_by_type (NodeType type, bool filtered = true) {
++ var children = new Vala.ArrayList<Node> ();
+
- public Gee.List<Node> get_children_by_types (NodeType[] types, bool filtered = true) {
- var children = new ArrayList<Node> ();
++ Vala.List<Node> all_children = per_type_children.get (type);
+ if (all_children != null) {
+ foreach (Node node in all_children) {
+ if (node.do_document || !filtered) {
+ children.add (node);
+ }
+ }
+ }
+
+ return children;
+ }
+
+ /**
+ * Returns a list of all children with the given types.
+ *
+ * @param types a list of node types
+ * @param filtered specifies whether nodes which are not browsable should appear in the list
+ */
- Gee.List<Node> all_children = per_type_children.get (type);
++ public Vala.List<Node> get_children_by_types (NodeType[] types, bool filtered = true) {
++ var children = new Vala.ArrayList<Node> ();
+
+ foreach (NodeType type in types) {
+ children.add_all (get_children_by_type (type, filtered));
+ }
+
+ return children;
+ }
+
+ /**
+ * Visits all children of this node with the given type with the specified Visitor.
+ *
+ * @param type a node type
+ * @param visitor the visitor to be called while traversing
+ * @param filtered specifies whether nodes which are not browsable should appear in the list
+ */
+ public void accept_children_by_type (NodeType type, Visitor visitor, bool filtered = true) {
- foreach (Gee.List<Node> children in per_type_children.values) {
++ Vala.List<Node> all_children = per_type_children.get (type);
+ if (all_children != null) {
+ foreach (Node node in all_children) {
+ if (node.do_document || !filtered) {
+ node.accept (visitor);
+ }
+ }
+ }
+ }
+
+ /**
+ * Visits all children of this node with the given types with the specified Visitor.
+ *
+ * @param types a list of node types
+ * @param visitor the visitor to be called while traversing
+ * @param filtered specifies whether nodes which are not browsable should appear in the list
+ */
+ public void accept_children (NodeType[] types, Visitor visitor, bool filtered = true) {
+ foreach (NodeType type in types) {
+ accept_children_by_type (type, visitor, filtered);
+ }
+ }
+
+ /**
+ * Visits all children of this node with the specified Visitor.
+ *
+ * @param visitor the visitor to be called while traversing
+ * @param filtered specifies whether nodes which are not browsable should appear in the list
+ */
+ public void accept_all_children (Visitor visitor, bool filtered = true) {
++ foreach (Vala.List<Node> children in per_type_children.get_values ()) {
+ foreach (Node node in children) {
+ if (node.do_document || !filtered) {
+ node.accept (visitor);
+ }
+ }
+ }
+ }
+
+ public Node? find_by_name (string name) {
+ if (name[0] == '@') {
+ return per_name_children.get (name.next_char ());
+ } else {
+ return per_name_children.get (name);
+ }
+ }
+
+ private Namespace? _nspace = null;
+ private Package? _package = null;
+ private string _full_name = null;
+
+ /**
+ * The corresponding namespace
+ */
+ public Namespace? nspace {
+ get {
+ if (this._nspace == null) {
+ Api.Item ast = this;
+ while (ast is Valadoc.Api.Namespace == false) {
+ ast = ast.parent;
+ if (ast == null) {
+ return null;
+ }
+ }
+ this._nspace = (Valadoc.Api.Namespace)ast;
+ }
+ return this._nspace;
+ }
+ }
+
+ /**
+ * The corresponding package such as a vapi or gir file
+ */
+ public Package? package {
+ get {
+ if (this._package == null) {
+ Api.Item ast = this;
+ while (ast is Valadoc.Api.Package == false) {
+ ast = ast.parent;
+ if (ast == null) {
+ return null;
+ }
+ }
+ this._package = (Valadoc.Api.Package)ast;
+ }
+ return this._package;
+ }
+ }
+
+ public Content.Comment? documentation {
+ internal set;
+ get;
+ }
+
+ /**
+ * Returns canonicalized absolute name (GLib.FileStream for instance)
+ */
+ public string? get_full_name () {
+ if (this._full_name == null) {
+ if (this.name == null) {
+ return null;
+ }
+
+ GLib.StringBuilder full_name = new GLib.StringBuilder (this.name);
+
+ if (this.parent != null) {
+ for (Item pos = this.parent; pos is Package == false ; pos = pos.parent) {
+ string name = ((Node)pos).name;
+ if (name != null) {
+ full_name.prepend_unichar ('.');
+ full_name.prepend (name);
+ }
+ }
+ }
+ this._full_name = full_name.str;
+ }
+ return this._full_name;
+ }
+
+ /**
+ * A comparison function used to sort nodes in alphabetical order
+ */
+ public int compare_to (Node node) {
+ return strcmp (name, node.name);
+ }
+
+ private bool is_keyword (string name) {
+ switch (name[0]) {
+ case 'a':
+ switch (name[1]) {
+ case 'b':
+ return name == "abstract";
+
+ case 's':
+ if (name[2] == '\0') {
+ return true;
+ }
+
+ return name == "async";
+ }
+ break;
+
+ case 'b':
+ switch (name[1]) {
+ case 'a':
+ return name == "base";
+
+ case 'r':
+ return name == "break";
+ }
+ break;
+
+ case 'c':
+ switch (name[1]) {
+ case 'a':
+ switch (name[2]) {
+ case 's':
+ return name == "case";
+
+ case 't':
+ return name == "catch";
+ }
+ break;
+
+ case 'l':
+ return name == "class";
+
+ case 'o':
+ if (name[2] != 'n') {
+ return false;
+ }
+
+ switch (name[3]) {
+ case 's':
+ if (name[4] == 't') {
+ switch (name[5]) {
+ case '\0':
+ return true;
+
+ case 'r':
+ return name == "construct";
+ }
+ }
+ break;
+
+ case 't':
+ return name == "continue";
+ }
+ break;
+ }
+ break;
+
+ case 'd':
+ switch (name[1]) {
+ case 'e':
+ switch (name[2]) {
+ case 'f':
+ return name == "default";
+
+ case 'l':
+ if (name[3] != 'e') {
+ return false;
+ }
+
+ switch (name[4]) {
+ case 'g':
+ return name == "delegate";
+
+ case 't':
+ return name == "delete";
+ }
+ break;
+ }
+ break;
+
+ case 'o':
+ return name[2] == '\0';
+
+ case 'y':
+ return name == "dynamic";
+ }
+ break;
+
+ case 'e':
+ switch (name[1]) {
+ case 'l':
+ return name == "else";
+
+ case 'n':
+ switch (name[2]) {
+ case 's':
+ return name == "ensures";
+
+ case 'u':
+ return name == "enum";
+ }
+ break;
+
+ case 'r':
+ return name == "errordomain";
+
+ case 'x':
+ return name == "extern";
+ }
+ break;
+
+ case 'f':
+ switch (name[1]) {
+ case 'a':
+ return name == "false";
+
+ case 'i':
+ return name == "finally";
+
+ case 'o':
+ if (name[2] != 'r') {
+ return false;
+ }
+
+ switch (name[3]) {
+ case '\0':
+ return true;
+
+ case 'e':
+ return name == "foreach";
+ }
+ break;
+ }
+ break;
+
+ case 'g':
+ return name == "get";
+
+ case 'i':
+ switch (name[1]) {
+ case 'f':
+ return name[2] == '\0';
+
+ case 'n':
+ switch (name[2]) {
+ case '\0':
+ return true;
+
+ case 'l':
+ return name == "inline";
+
+ case 't':
+ return name == "interface" || name == "internal";
+ }
+ break;
+
+ case 's':
+ return name[2] == '\0';
+ }
+ break;
+
+ case 'l':
+ return name == "lock";
+
+ case 'n':
+ switch (name[1]) {
+ case 'a':
+ return name == "namespace";
+
+ case 'e':
+ return name == "new";
+
+ case 'u':
+ return name == "null";
+ }
+ break;
+
+ case 'o':
+ switch (name[1]) {
+ case 'u':
+ return name == "out";
+
+ case 'v':
+ return name == "override";
+
+ case 'w':
+ return name == "owned";
+ }
+ break;
+
+ case 'p':
+ switch (name[1]) {
+ case 'a':
+ return name == "params";
+
+ case 'r':
+ switch (name[2]) {
+ case 'i':
+ return name == "private";
+
+ case 'o':
+ return name == "protected";
+ }
+ break;
+ case 'u':
+ return name == "public";
+ }
+ break;
+
+ case 'r':
+ if (name[1] != 'e') {
+ return false;
+ }
+
+ switch (name[2]) {
+ case 'f':
+ return name[3] == '\0';
+
+ case 'q':
+ return name == "requires";
+
+ case 't':
+ return name == "return";
+ }
+ break;
+
+ case 's':
+ switch (name[1]) {
+ case 'e':
+ switch (name[2]) {
+ case 'a':
+ return name == "sealed";
+
+ case 't':
+ return name[3] == '\0';
+ }
+ break;
+
+ case 'i':
+ switch (name[2]) {
+ case 'g':
+ return name == "signal";
+ case 'z':
+ return name == "sizeof";
+ }
+ break;
+
+ case 't':
+ switch (name[2]) {
+ case 'a':
+ return name == "static";
+
+ case 'r':
+ return name == "struct";
+ }
+ break;
+
+ case 'w':
+ return name == "switch";
+ }
+ break;
+
+ case 't':
+ switch (name[1]) {
+ case 'h':
+ switch (name[2]) {
+ case 'i':
+ return name == "this";
+
+ case 'r':
+ if (name[3] == 'o' && name[4] == 'w') {
+ return name[5] == '\0' || (name[5] == 's' && name[6] == '\0');
+ }
+ break;
+ }
+ break;
+
+ case 'r':
+ switch (name[2]) {
+ case 'u':
+ return name == "true";
+
+ case 'y':
+ return name[3] == '\0';
+ }
+ break;
+
+ case 'y':
+ return name == "typeof";
+ }
+ break;
+
+ case 'u':
+ switch (name[1]) {
+ case 'n':
+ return name == "unowned";
+
+ case 's':
+ return name == "using";
+ }
+ break;
+
+ case 'v':
+ switch (name[1]) {
+ case 'a':
+ return name == "var";
+
+ case 'i':
+ return name == "virtual";
+
+ case 'o':
+ switch (name[2]) {
+ case 'i':
+ return name == "void";
+
+ case 'l':
+ return name == "volatile";
+ }
+ break;
+ }
+ break;
+
+ case 'w':
+ switch (name[1]) {
+ case 'e':
+ return name == "weak";
+
+ case 'h':
+ return name == "while";
+ }
+ break;
+
+ case 'y':
+ return name == "yield";
+ }
+
+ return false;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* node.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2007-20012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ /**
+ * Specifies the context of a node.
+ */
+ public enum Valadoc.Api.NodeType {
+ CLASS,
+ CONSTANT,
+ CREATION_METHOD,
+ DELEGATE,
+ ENUM,
+ ENUM_VALUE,
+ ERROR_CODE,
+ ERROR_DOMAIN,
+ FIELD,
+ FORMAL_PARAMETER,
+ INTERFACE,
+ METHOD,
+ NAMESPACE,
+ PACKAGE,
+ PROPERTY,
+ PROPERTY_ACCESSOR,
+ SIGNAL,
+ STATIC_METHOD,
+ STRUCT,
+ TYPE_PARAMETER;
+
+ public string to_string () {
+ switch (this) {
+ case CLASS:
+ return "CLASS";
+
+ case CONSTANT:
+ return "CONSTANT";
+
+ case CREATION_METHOD:
+ return "CREATION_METHOD";
+
+ case DELEGATE:
+ return "DELEGATE";
+
+ case ENUM:
+ return "ENUM";
+
+ case ENUM_VALUE:
+ return "ENUM_VALUE";
+
+ case ERROR_CODE:
+ return "ERROR_CODE";
+
+ case ERROR_DOMAIN:
+ return "ERROR_DOMAIN";
+
+ case FIELD:
+ return "FIELD";
+
+ case FORMAL_PARAMETER:
+ return "FORMAL_PARAMETER";
+
+ case INTERFACE:
+ return "INTERFACE";
+
+ case METHOD:
+ return "METHOD";
+
+ case NAMESPACE:
+ return "NAMESPACE";
+
+ case PACKAGE:
+ return "PACKAGE";
+
+ case PROPERTY:
+ return "PROPERTY";
+
+ case PROPERTY_ACCESSOR:
+ return "PROPERTY_ACCESSOR";
+
+ case SIGNAL:
+ return "SIGNAL";
+
+ case STATIC_METHOD:
+ return "STATIC_METHOD";
+
+ case STRUCT:
+ return "STRUCT";
+
+ case TYPE_PARAMETER:
+ return "TYPE_PARAMETER";
+
+ default:
+ assert_not_reached ();
+ }
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* package.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- internal void set_dependency_list (ArrayList<Package> list) {
++
+ using Valadoc.Content;
+ using Valadoc.Importer;
+
+ public class Valadoc.Api.Package : Node {
+
+ /**
+ * Specifies whether this package is a dependency
+ */
+ public bool is_package {
+ private set;
+ get;
+ }
+
- private ArrayList<Package> _dependencies;
++ internal void set_dependency_list (Vala.ArrayList<Package> list) {
+ this._dependencies = list;
+ }
+
- public Collection<Package> get_full_dependency_list () {
- ArrayList<Package> list = new ArrayList<Package> ();
++ private Vala.ArrayList<Package> _dependencies;
+
+ /**
+ * Returns a list with all dependencies
+ */
- return list.read_only_view;
++ public Vala.Collection<Package> get_full_dependency_list () {
++ Vala.ArrayList<Package> list = new Vala.ArrayList<Package> ();
+
+ if (this._dependencies == null) {
- return list.read_only_view;
++ return list;
+ }
+
+ foreach (Package pkg in this._dependencies) {
+ if (list.contains ( pkg ) == false) {
+ list.add (pkg);
+ }
+
+ var pkg_list = pkg.get_full_dependency_list ();
+ foreach (Package pkg2 in pkg_list) {
+ if (list.contains (pkg2) == false) {
+ list.add (pkg2);
+ }
+ }
+ }
- public Collection<Package> get_dependency_list () {
++ return list;
+ }
+
- return Collection.empty<Package> ();
++ public Vala.Collection<Package> get_dependency_list () {
+ if (this._dependencies == null) {
- return this._dependencies.read_only_view;
++ return new Vala.ArrayList<Package> ();
+ }
+
- private HashMap<string?, ArrayList<Symbol>> deprecated;
++ return this._dependencies;
+ }
+
+ public Package (string name, bool is_package, void* data) {
+ base (null, null, name, data);
+
+ this.is_package = is_package;
+ this.parent = null;
+ }
+
+ // <version, symbols>
- deprecated = new HashMap<string?, ArrayList<Symbol>> ();
++ private Vala.HashMap<string, Vala.ArrayList<Symbol>> deprecated;
+
+ internal void register_deprecated_symbol (Symbol symbol, string? version) {
+ if (deprecated == null) {
- ArrayList<Symbol> list = deprecated.get (version);
++ deprecated = new Vala.HashMap<string, Vala.ArrayList<Symbol>> (str_hash, str_equal);
++ }
++
++ if (version == null) {
++ version = "0xdeadbeef";
+ }
+
- list = new ArrayList<Symbol> ();
++ Vala.ArrayList<Symbol> list = deprecated.get (version);
+ if (list == null) {
- public Map<string?, Collection<Symbol>> get_deprecated_symbols () {
++ list = new Vala.ArrayList<Symbol> ();
+ deprecated.set (version, list);
+ }
+
+ list.add (symbol);
+ }
+
- return Map<string?, Collection<Symbol>>.empty<string?, Collection<Symbol>> ();
++ public Vala.Map<string, Vala.Collection<Symbol>> get_deprecated_symbols () {
+ if (deprecated == null) {
++ return new Vala.HashMap<string, Vala.Collection<Symbol>> (str_hash, str_equal);
+ }
+
+ return deprecated;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override bool is_browsable (Settings settings) {
+ return !(this.is_package && settings.with_deps == false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.PACKAGE; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_package (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ return new SignatureBuilder ()
+ .append_keyword ("package")
+ .append (name)
+ .get ();
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* pointer.vala
+ *
+ * Copyright (C) 2008 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents a pointer declaration.
+ */
+ public class Valadoc.Api.Pointer : Item {
+
+ /**
+ * The type the pointer is referring to.
+ */
+ public Item data_type {
+ set;
+ get;
+ }
+
+ public Pointer (Item parent, void* data) {
+ base (data);
+
+ this.parent = parent;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ return new SignatureBuilder ()
+ .append_content (data_type.signature)
+ .append ("*", false)
+ .get ();
+ }
+ }
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* property.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- internal set;
+
++using Valadoc.Content;
+
+ /**
+ * Represents a property declaration.
+ */
+ public class Valadoc.Api.Property : Member {
+ private PropertyBindingType binding_type;
+ private string? dbus_name;
+ private string? cname;
+
+ public Property (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, string? dbus_name, bool is_dbus_visible,
+ PropertyBindingType binding_type, void* data)
+ {
+ base (parent, file, name, accessibility, comment, data);
+
+ this.is_dbus_visible = is_dbus_visible;
+ this.binding_type = binding_type;
+
+ this.dbus_name = dbus_name;
+ this.cname = cname;
+ }
+
+ /**
+ * Returns the name of this method as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * Returns the dbus-name.
+ */
+ public string get_dbus_name () {
+ return dbus_name;
+ }
+
+ /**
+ * The property type.
+ *
+ * @return The property type or null for void
+ */
+ public TypeReference? property_type {
+ set;
+ get;
+ }
+
+ /**
+ * Specifies whether the property is virtual.
+ */
+ public bool is_virtual {
+ get {
+ return binding_type == PropertyBindingType.VIRTUAL;
+ }
+ }
+
+ /**
+ * Specifies whether the property is abstract.
+ */
+ public bool is_abstract {
+ get {
+ return binding_type == PropertyBindingType.ABSTRACT;
+ }
+ }
+
+ /**
+ * Specifies whether the property is override.
+ */
+ public bool is_override {
+ get {
+ return binding_type == PropertyBindingType.OVERRIDE;
+ }
+ }
+
+ /**
+ * Specifies whether the property is visible.
+ */
+ public bool is_dbus_visible {
+ private set;
+ get;
+ }
+
+ public PropertyAccessor? setter {
- internal set;
++ set;
+ get;
+ }
+
+ public PropertyAccessor? getter {
++ set;
+ get;
+ }
+
+ /**
+ * Specifies the virtual or abstract property this property overrides.
+ */
+ public Property base_property {
+ set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void parse_comments (Settings settings, DocumentationParser parser) {
+ if (getter != null && getter.is_browsable (settings)) {
+ getter.parse_comments (settings, parser);
+ }
+
+ if (setter != null && setter.is_browsable (settings)) {
+ setter.parse_comments (settings, parser);
+ }
+
+ base.parse_comments (settings, parser);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void check_comments (Settings settings, DocumentationParser parser) {
+ if (getter != null && getter.is_browsable (settings)) {
+ getter.check_comments (settings, parser);
+ }
+
+ if (setter != null && setter.is_browsable (settings)) {
+ setter.check_comments (settings, parser);
+ }
+
+ base.check_comments (settings, parser);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ signature.append_keyword (accessibility.to_string ());
+ if (is_abstract) {
+ signature.append_keyword ("abstract");
+ } else if (is_override) {
+ signature.append_keyword ("override");
+ } else if (is_virtual) {
+ signature.append_keyword ("virtual");
+ }
+
+ signature.append_content (property_type.signature);
+ signature.append_symbol (this);
+ signature.append ("{");
+
+ if (setter != null && setter.do_document) {
+ signature.append_content (setter.signature);
+ }
+
+ if (getter != null && getter.do_document) {
+ signature.append_content (getter.signature);
+ }
+
+ signature.append ("}");
+
+ return signature.get ();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.PROPERTY; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_property (this);
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* propertyaccessor.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents a get or set accessor of a property.
+ */
+ public class Valadoc.Api.PropertyAccessor : Symbol {
+ private PropertyAccessorType type;
+ private Ownership ownership;
+ private string? cname;
+
+ public PropertyAccessor (Property parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ string? cname, PropertyAccessorType type, Ownership ownership, void* data)
+ {
+ base (parent, file, name, accessibility, data);
+
+ this.ownership = ownership;
+ this.cname = cname;
+ this.type = type;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.PROPERTY_ACCESSOR; }
+ }
+
+ /**
+ * Returns the name of this property accessor as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ }
+
+ /**
+ * Specifies whether this accessor may be used to construct the property.
+ */
+ public bool is_construct {
+ get {
+ return (type & PropertyAccessorType.CONSTRUCT) != 0;
+ }
+ }
+
+ /**
+ * Specifies whether this accessor is a setter.
+ */
+ public bool is_set {
+ get {
+ return (type & PropertyAccessorType.SET) != 0;
+ }
+ }
+
+ /**
+ * Specifies whether this accessor is a getter.
+ */
+ public bool is_get {
+ get {
+ return (type & PropertyAccessorType.GET) != 0;
+ }
+ }
+
+ /**
+ * Specifies whether the property is owned.
+ */
+ public bool is_owned {
+ get {
+ return ownership == Ownership.OWNED;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ // FIXME
+ if (!do_document) {
+ return signature.get ();
+ }
+
+ if (((Property) parent).accessibility != accessibility) {
+ signature.append_keyword (accessibility.to_string ());
+ }
+
+ if (is_set || is_construct) {
+ if (is_construct) {
+ signature.append_keyword ("construct");
+ }
+ if (is_set) {
+ signature.append_keyword ("set");
+ }
+ } else if (is_get) {
+ if (is_owned) {
+ signature.append_keyword ("owned");
+ }
+ signature.append_keyword ("get");
+ }
+ signature.append (";", false);
+
+ return signature.get ();
+ }
+ }
+
--- /dev/null
+ /* propertyaccessor.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
++
+ public enum Valadoc.Api.PropertyAccessorType {
+ CONSTRUCT = 1 << 0,
+ SET = 1 << 1,
+ GET = 1 << 2;
+
+ public string to_string () {
+ if ((this & PropertyAccessorType.CONSTRUCT) != 0) {
+ if ((this & PropertyAccessorType.SET) != 0) {
+ return "construct set";
+ }
+ return "construct";
+ } else if ((this & PropertyAccessorType.SET) != 0) {
+ return "set";
+ } else if ((this & PropertyAccessorType.GET) != 0) {
+ return "get";
+ }
+
+ assert_not_reached ();
+ }
+ }
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* signal.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents an signal.
+ */
+ public class Valadoc.Api.Signal : Member, Callable {
+ private string? default_impl_cname;
+ private string? dbus_name;
+ private string? cname;
+
+
+ /**
+ * {@inheritDoc}
+ */
+ internal string? implicit_array_length_cparameter_name {
+ get;
+ set;
+ }
+
+
+ public Signal (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, string? default_impl_cname, string? dbus_name, bool is_dbus_visible,
+ bool is_virtual, void* data)
+ {
+ base (parent, file, name, accessibility, comment, data);
+
+ this.default_impl_cname = default_impl_cname;
+ this.dbus_name = dbus_name;
+ this.cname = cname;
+
+ this.is_dbus_visible = is_dbus_visible;
+ this.is_virtual = is_virtual;
+ }
+
+ /**
+ * Returns the name of this signal as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ public string? get_default_impl_cname () {
+ return default_impl_cname;
+ }
+
+ /**
+ * Returns the dbus-name.
+ */
+ public string get_dbus_name () {
+ return dbus_name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public TypeReference? return_type {
+ set;
+ get;
+ }
+
+ /**
+ * Specifies whether this signal is virtual
+ */
+ public bool is_virtual {
+ private set;
+ get;
+ }
+
+ /**
+ * Specifies whether this signal is visible for dbus
+ */
+ public bool is_dbus_visible {
+ private set;
+ get;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ signature.append_keyword (accessibility.to_string ());
+ if (is_virtual) {
+ signature.append_keyword ("virtual");
+ }
+
+ signature.append_keyword ("signal");
+
+ signature.append_content (return_type.signature);
+ signature.append_symbol (this);
+ signature.append ("(");
+
+ bool first = true;
+ foreach (Node param in get_children_by_type (NodeType.FORMAL_PARAMETER, false)) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, !first);
+ first = false;
+ }
+
+ signature.append (")", false);
+
+ return signature.get ();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.SIGNAL; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_signal (this);
+ }
+ }
+
--- /dev/null
-using Valadoc.Content;
+ /* signaturebuilder.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Builds up a signature from the given items.
+ */
+ public class Valadoc.Api.SignatureBuilder {
+ private Run run;
+ private Inline last_appended;
+
+ /**
+ * Creates a new SignatureBuilder
+ */
+ public SignatureBuilder () {
+ run = new Run (Run.Style.NONE);
+ }
+
+ private void append_text (string text) {
+ if (last_appended is Text) {
+ ((Text) last_appended).content += text;
+ } else {
+ run.content.add (last_appended = new Text (text));
+ }
+ }
+
+ /**
+ * Adds text onto the end of the builder.
+ *
+ * @param text a string
+ * @param spaced add a space at the front of the string if necessary
+ * @return this
+ */
+ public SignatureBuilder append (string text, bool spaced = true) {
+ string content = (last_appended != null && spaced ? " " : "") + text;
+ append_text (content);
+ return this;
+ }
+
+ /**
+ * Adds text onto the end of the builder.
+ *
+ * @param text a string
+ * @param spaced add a space at the front of the string if necessary
+ * @return this
+ */
+ public SignatureBuilder append_attribute (string text, bool spaced = true) {
+ string content = (last_appended != null && spaced ? " " : "") + text;
+ append_text (content);
+ return this;
+ }
+
+ /**
+ * Adds highlighted text onto the end of the builder.
+ *
+ * @param text a string
+ * @param spaced add a space at the front of the string if necessary
+ * @return this
+ */
+ public SignatureBuilder append_highlighted (string text, bool spaced = true) {
+ string content = (last_appended != null && spaced ? " " : "") + text;
+ Run inner = new Run (Run.Style.ITALIC);
+ inner.content.add (new Text (content));
+ return append_content (inner, spaced);
+ }
+
+ /**
+ * Adds a Inline onto the end of the builder.
+ *
+ * @param content a content
+ * @param spaced add a space at the front of the inline if necessary
+ * @return this
+ */
+ public SignatureBuilder append_content (Inline content, bool spaced = true) {
+ if (last_appended != null && spaced) {
+ append_text (" ");
+ }
+ run.content.add (last_appended = content);
+ return this;
+ }
+
+ /**
+ * Adds a keyword onto the end of the builder.
+ *
+ * @param keyword a keyword
+ * @param spaced add a space at the front of the keyword if necessary
+ * @return this
+ */
+ public SignatureBuilder append_keyword (string keyword, bool spaced = true) {
+ Run inner = new Run (Run.Style.LANG_KEYWORD);
+ inner.content.add (new Text (keyword));
+ return append_content (inner, spaced);
+ }
+
+ /**
+ * Adds a symbol onto the end of the builder.
+ *
+ * @param node a node
+ * @param spaced add a space at the front of the node if necessary
+ * @return this
+ */
+ public SignatureBuilder append_symbol (Node node, bool spaced = true) {
+ Run inner = new Run (Run.Style.BOLD);
+ inner.content.add (new SymbolLink (node, node.name));
+ return append_content (inner, spaced);
+ }
+
+ /**
+ * Adds a type onto the end of the builder.
+ *
+ * @param node a node
+ * @param spaced add a space at the front of the node if necessary
+ * @return this
+ */
+ public SignatureBuilder append_type (Node node, bool spaced = true) {
+ Run.Style style = Run.Style.LANG_TYPE;
+ if (node is TypeSymbol && ((TypeSymbol)node).is_basic_type) {
+ style = Run.Style.LANG_BASIC_TYPE;
+ }
+
+ Run inner = new Run (style);
+ inner.content.add (new SymbolLink (node, node.name));
+ return append_content (inner, spaced);
+ }
+
+ /**
+ * Adds a type name onto the end of the builder.
+ *
+ * @param name a type name
+ * @param spaced add a space at the front of the type name if necessary
+ * @return this
+ */
+ public SignatureBuilder append_type_name (string name, bool spaced = true) {
+ Run inner = new Run (Run.Style.LANG_TYPE);
+ inner.content.add (new Text (name));
+ return append_content (inner, spaced);
+ }
+
+ /**
+ * Adds a literal onto the end of the builder.
+ *
+ * @param literal a literal
+ * @param spaced add a space at the front of the literal if necessary
+ * @return this
+ */
+ public SignatureBuilder append_literal (string literal, bool spaced = true) {
+ Run inner = new Run (Run.Style.LANG_LITERAL);
+ inner.content.add (new Text (literal));
+ return append_content (inner, spaced);
+ }
+
+ /**
+ * The content
+ */
+ public new Run get () {
+ return run;
+ }
+ }
+
--- /dev/null
-
+ /* sourcecomment.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ /**
+ * A documentation comment used by valadoc
+ */
+ public class Valadoc.Api.SourceComment {
+ public SourceFile file {
+ private set;
+ get;
+ }
+
+ /**
+ * The text describing the referenced source code.
+ */
+ public string content {
+ private set;
+ get;
+ }
+
+ /**
+ * The first line number of the referenced source code.
+ */
+ public int first_line {
+ private set;
+ get;
+ }
+
+ /**
+ * The first column number of the referenced source code.
+ */
+ public int first_column {
+ private set;
+ get;
+ }
+
+ /**
+ * The last line number of the referenced source code.
+ */
+ public int last_line {
+ private set;
+ get;
+ }
+
+ /**
+ * The last column number of the referenced source code.
+ */
+ public int last_column {
+ private set;
+ get;
+ }
+
+ public SourceComment (string content, SourceFile file, int first_line, int first_column,
+ int last_line, int last_column)
+ {
+ this.first_column = first_column;
+ this.last_column = last_column;
+ this.first_line = first_line;
+ this.last_line = last_line;
+ this.content = content;
+ this.file = file;
+ }
+ }
+
+
--- /dev/null
+ /* sourcefile.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Brosch Florian <flo.brosch@gmail.com>
+ */
+
++
+ /**
+ * Represents a source file
+ */
+ public class Valadoc.Api.SourceFile : Object {
+
+ public Package package {
+ private set;
+ get;
+ }
+
+ public string relative_path {
+ private set;
+ get;
+ }
+
+ public string? relative_c_path {
+ private set;
+ get;
+ }
+
+ public string get_name () {
+ return Path.get_basename (relative_path);
+ }
+
+ public void* data {
+ private set;
+ get;
+ }
+
+ public SourceFile (Package package, string relative_path, string? relative_c_path, void* data) {
+ this.relative_c_path = relative_c_path;
+ this.relative_path = relative_path;
+ this.package = package;
+ this.data = data;
+ }
+ }
+
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* struct.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private Set<Struct> _known_child_structs = new TreeSet<Struct> ();
+
++using Valadoc.Content;
+
+ /**
+ * Represents a struct declaration.
+ */
+ public class Valadoc.Api.Struct : TypeSymbol {
+ private string? dup_function_cname;
+ private string? copy_function_cname;
+ private string? free_function_cname;
+ private string? destroy_function_cname;
+ private string? type_id;
+ private string? cname;
+
+ public Struct (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? cname, string? type_macro_name,
+ string? type_function_name, string? type_id, string? dup_function_cname,
+ string? copy_function_cname, string? destroy_function_cname,
+ string? free_function_cname, bool is_basic_type, void* data)
+ {
+ base (parent, file, name, accessibility, comment, type_macro_name, null, null,
+ type_function_name, is_basic_type, data);
+
+ this.dup_function_cname = dup_function_cname;
+ this.copy_function_cname = copy_function_cname;
+ this.free_function_cname = free_function_cname;
+ this.destroy_function_cname = destroy_function_cname;
+
+ this.cname = cname;
+ }
+
+ /**
+ * Specifies the base struct.
+ */
+ public TypeReference? base_type {
+ set;
+ get;
+ }
+
+
+ /**
+ * Returns the name of this struct as it is used in C.
+ */
+ public string? get_cname () {
+ return cname;
+ }
+
+ /**
+ * Returns the C symbol representing the runtime type id for this data type.
+ */
+ public string? get_type_id () {
+ return type_id;
+ }
+
+ /**
+ * Returns the C function name that duplicates instances of this data
+ * type.
+ */
+ public string? get_dup_function_cname () {
+ return dup_function_cname;
+ }
+
+ /**
+ * Returns the C function name that copies instances of this data
+ * type.
+ */
+ public string? get_copy_function_cname () {
+ return copy_function_cname;
+ }
+
+ /**
+ * Returns the C function name that frees instances of this data type.
+ */
+ public string? get_free_function_cname () {
+ return free_function_cname;
+ }
+
+ /**
+ * Returns the C function name that destroys instances of this data type.
+ */
+ public string? get_destroy_function_cname () {
+ return destroy_function_cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type {
+ get { return NodeType.STRUCT; }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_struct (this);
+ }
+
+
- public Collection<Struct> get_known_child_structs () {
- return _known_child_structs.read_only_view;
++ private Vala.Set<Struct> _known_child_structs = new Vala.HashSet<Struct> ();
+
+ /**
+ * Returns a list of all known structs based on this struct
+ */
++ public Vala.Collection<Struct> get_known_child_structs () {
++ return _known_child_structs;
+ }
+
+ public void register_child_struct (Struct stru) {
+ if (this.base_type != null) {
+ ((Struct) this.base_type.data_type).register_child_struct (stru);
+ }
+
+ _known_child_structs.add (stru);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ signature.append_keyword (accessibility.to_string ());
+ signature.append_keyword ("struct");
+ signature.append_symbol (this);
+
+ var type_parameters = get_children_by_type (NodeType.TYPE_PARAMETER, false);
+ if (type_parameters.size > 0) {
+ signature.append ("<", false);
+ bool first = true;
+ foreach (Item param in type_parameters) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, false);
+ first = false;
+ }
+ signature.append (">", false);
+ }
+
+ if (base_type != null) {
+ signature.append (":");
+
+ signature.append_content (base_type.signature);
+ }
+
+ return signature.get ();
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* symbol.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- private ArrayList<Attribute> attributes;
+
+ /**
+ * Represents a node in the symbol tree.
+ */
+ public abstract class Valadoc.Api.Symbol : Node {
- attributes = new ArrayList<Attribute> ();
++ private Vala.ArrayList<Attribute> attributes;
+
+ public bool is_deprecated {
+ default = false;
+ private set;
+ get;
+ }
+
+ public Symbol (Node parent, SourceFile file, string? name, SymbolAccessibility accessibility,
+ void* data)
+ {
+ base (parent, file, name, data);
+
+ this.accessibility = accessibility;
+ }
+
+ public void add_attribute (Attribute att) {
+ if (attributes == null) {
- public Collection<Attribute> get_attributes () {
++ attributes = new Vala.ArrayList<Attribute> ();
+ }
+
+ // register deprecated symbols:
+ if (att.name == "Version") {
+ AttributeArgument? deprecated = att.get_argument ("deprecated");
+ AttributeArgument? version = att.get_argument ("deprecated_since");
+ if ((deprecated != null && deprecated.get_value_as_boolean ()) || version != null) {
+ string? version_str = (version != null) ? version.get_value_as_string () : null;
+
+ package.register_deprecated_symbol (this, version_str);
+ is_deprecated = true;
+ }
+ } else if (att.name == "Deprecated") {
+ AttributeArgument? version = att.get_argument ("version");
+ string? version_str = (version != null) ? version.get_value_as_string () : null;
+
+ package.register_deprecated_symbol (this, version_str);
+ is_deprecated = true;
+ }
+
+ attributes.add (att);
+ }
+
- return Collection<Attribute>.empty<Attribute> ();
++ public Vala.Collection<Attribute> get_attributes () {
+ if (attributes == null) {
++ return new Vala.ArrayList<Attribute> ();
+ } else {
+ return attributes;
+ }
+ }
+
+ public Attribute? get_attribute (string name) {
+ if (attributes != null) {
+ foreach (Attribute att in attributes) {
+ if (att.name == name) {
+ return att;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override bool is_browsable (Settings settings) {
+ if (!settings._private && this.is_private) {
+ return false;
+ }
+ if (!settings._internal && this.is_internal) {
+ return false;
+ }
+ if (!settings._protected && this.is_protected) {
+ return false;
+ }
+
+ Item? pos = parent;
+ while (pos != null && pos is Symbol && pos is Namespace == false) {
+ if (((Symbol) pos).is_browsable (settings) == false) {
+ return false;
+ }
+ pos = pos.parent;
+ }
+
+ return true;
+ }
+
+ public SymbolAccessibility accessibility {
+ private set;
+ get;
+ }
+
+ /**
+ * Specifies whether this symbol is public.
+ */
+ public bool is_public {
+ get {
+ return accessibility == SymbolAccessibility.PUBLIC;
+ }
+ }
+
+ /**
+ * Specifies whether this symbol is protected.
+ */
+ public bool is_protected {
+ get {
+ return accessibility == SymbolAccessibility.PROTECTED;
+ }
+ }
+
+ /**
+ * Specifies whether this symbol is internal.
+ */
+ public bool is_internal {
+ get {
+ return accessibility == SymbolAccessibility.INTERNAL;
+ }
+ }
+
+ /**
+ * Specifies whether this symbol is private.
+ */
+ public bool is_private {
+ get {
+ return accessibility == SymbolAccessibility.PRIVATE;
+ }
+ }
+ }
+
--- /dev/null
-using Valadoc.Importer;
-using Gee;
-
+ /* tree.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private Deque<InheritDocContainer> inheritdocs = new LinkedList<InheritDocContainer> ();
- private ArrayList<string> external_c_files = new ArrayList<string>();
- private ArrayList<Package> packages = new ArrayList<Package>();
+
++using Valadoc.Importer;
+
+ /**
+ * The root of the code tree.
+ */
+ public class Valadoc.Api.Tree {
- public Collection<string> get_external_c_files () {
- return external_c_files.read_only_view;
++ private Vala.List<InheritDocContainer> inheritdocs = new Vala.ArrayList<InheritDocContainer> ();
++ private Vala.ArrayList<string> external_c_files = new Vala.ArrayList<string>(str_equal);
++ private Vala.ArrayList<Package> packages = new Vala.ArrayList<Package>();
+ private Package source_package = null;
+ private Settings settings;
+ private ErrorReporter reporter;
+ private Highlighter.Highlighter _highlighter;
+ private CTypeResolver _cresolver = null;
+ private Package _source_package;
+
+
+ private class InheritDocContainer {
+ public unowned Taglets.InheritDoc taglet;
+ public unowned Api.Node taglet_container;
+
+ public InheritDocContainer (Api.Node taglet_container, Taglets.InheritDoc taglet) {
+ this.taglet_container = taglet_container;
+ this.taglet = taglet;
+ }
+ }
+
+
+ public void add_package(Package package) {
+ this.packages.add (package);
+ }
+
+ public void* data {
+ set;
+ get;
+ }
+
+ public Highlighter.Highlighter highlighter {
+ get {
+ if (_highlighter == null) {
+ _highlighter = new Highlighter.Highlighter ();
+ }
+
+ return _highlighter;
+ }
+ }
+
+ /**
+ * The root of the wiki tree.
+ */
+ public WikiPageTree? wikitree {
+ private set;
+ get;
+ }
+
+ /**
+ * Returns a list of C source files.
+ *
+ * @return list of C source files
+ */
- public Collection<Package> get_package_list () {
- return this.packages.read_only_view;
++ public Vala.Collection<string> get_external_c_files () {
++ return external_c_files;
+ }
+
+ public void add_external_c_files (string name) {
+ external_c_files.add (name);
+ }
+
+
+ /**
+ * Returns a list of all packages in the tree
+ *
+ * @return list of all packages
+ */
- ArrayList<Package> deplst = new ArrayList<Package> ();
++ public Vala.Collection<Package> get_package_list () {
++ return this.packages;
+ }
+
+ private void add_dependencies_to_source_package () {
+ if ( this.source_package != null ) {
- InheritDocContainer container = this.inheritdocs.poll_head ();
++ Vala.ArrayList<Package> deplst = new Vala.ArrayList<Package> ();
+ foreach (Package pkg in this.packages) {
+ if (pkg != this.source_package) {
+ deplst.add (pkg);
+ }
+ }
+ this.source_package.set_dependency_list (deplst);
+ }
+ }
+
+ /**
+ * Visits this node with the specified Visitor.
+ *
+ * @param visitor the visitor to be called while traversing
+ */
+ public void accept (Visitor visitor) {
+ visitor.visit_tree (this);
+ }
+
+ /**
+ * Visits all children of this node with the given types with the specified Visitor.
+ *
+ * @param visitor the visitor to be called while traversing
+ */
+ public void accept_children (Visitor visitor) {
+ foreach (Node node in packages) {
+ node.accept (visitor);
+ }
+ }
+
+ private Node? search_relative_to (Node element, string[] path) {
+ Api.Node? node = element;
+
+ foreach (string name in path) {
+ node = node.find_by_name (name);
+ if (node == null) {
+ break;
+ }
+ }
+
+ if (node == null && element.parent != null) {
+ node = search_relative_to ((Node) element.parent, path);
+ }
+
+ return node;
+ }
+
+ public Node? search_symbol_path (Node? element, string[] path) {
+ Api.Node? node = null;
+
+ // relative to element
+ if (element != null) {
+ node = search_relative_to (element, path);
+ if (node != null) {
+ return node;
+ }
+ }
+
+
+ // absolute
+ foreach (Package package in packages) {
+ // search in root namespace
+
+ Node? global = package.find_by_name ("");
+ if (global != null) {
+ node = search_relative_to (global, path);
+ if (node != null) {
+ return node;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public TypeSymbol? search_symbol_type_cstr (string cname) {
+ if (_cresolver == null) {
+ _cresolver = new CTypeResolver (this);
+ }
+
+ return _cresolver.resolve_symbol_type (cname);
+ }
+
+ public Node? search_symbol_cstr (Node? element, string cname) {
+ if (_cresolver == null) {
+ _cresolver = new CTypeResolver (this);
+ }
+
+ return _cresolver.resolve_symbol (element, cname);
+ }
+
+ public Node? search_symbol_str (Node? element, string symname) {
+ string[] path = split_name (symname);
+
+ var node = search_symbol_path (element, path);
+ if (node != null) {
+ return node;
+ }
+
+ if (path.length >= 2 && path[path.length-2] == path[path.length-2]) {
+ path[path.length-2] = path[path.length-2]+"."+path[path.length-1];
+ path.resize (path.length-1);
+ return search_symbol_path (element, path);
+ }
+
+ return null;
+ }
+
+ private string[] split_name (string full_name) {
+ string[] params = (full_name).split (".", -1);
+ int i = 0; while (params[i] != null) i++;
+ params.length = i;
+ return params;
+ }
+
+ public Tree (ErrorReporter reporter, Settings settings, void* data = null) {
+ this.settings = settings;
+ this.reporter = reporter;
+ this.data = data;
+ }
+
+ // copied from valacodecontext.vala
+ private string? get_file_path (string basename, string[] directories) {
+ string filename = null;
+
+ if (directories != null) {
+ foreach (string dir in directories) {
+ filename = Path.build_filename (dir, basename);
+ if (FileUtils.test (filename, FileTest.EXISTS)) {
+ return filename;
+ }
+ }
+ }
+
+ foreach (string dir in Environment.get_system_data_dirs ()) {
+ filename = Path.build_filename (dir, basename);
+ if (FileUtils.test (filename, FileTest.EXISTS)) {
+ return filename;
+ }
+ }
+
+ return null;
+ }
+
+ public bool create_tree ( ) {
+ this.add_dependencies_to_source_package ();
+ return true;
+ }
+
+ private Package? get_source_package () {
+ if (_source_package == null) {
+ foreach (Package pkg in packages) {
+ if (!pkg.is_package) {
+ _source_package = pkg;
+ break;
+ }
+ }
+ }
+
+ return _source_package;
+ }
+
+ private void parse_wiki (DocumentationParser docparser) {
+ this.wikitree = new WikiPageTree ();
+ var pkg = get_source_package ();
+ if (pkg != null) {
+ wikitree.parse (settings, docparser, pkg, reporter);
+ }
+ }
+
+ private void check_wiki (DocumentationParser docparser) {
+ Package pkg = get_source_package ();
+ if (pkg != null) {
+ wikitree.check (settings, docparser, pkg);
+ }
+ }
+
+ public void parse_comments (DocumentationParser docparser) {
+ parse_wiki (docparser);
+
+ foreach (Package pkg in this.packages) {
+ if (pkg.is_browsable (settings)) {
+ pkg.parse_comments (settings, docparser);
+ }
+ }
+ }
+
+ public void check_comments (DocumentationParser docparser) {
+ check_wiki (docparser);
+
+ foreach (Package pkg in this.packages) {
+ if (pkg.is_browsable (settings)) {
+ pkg.check_comments (settings, docparser);
+ postprocess_inheritdoc (docparser);
+ }
+ }
+ }
+
+ internal void register_inheritdoc (Api.Node container, Taglets.InheritDoc taglet) {
+ inheritdocs.add (new InheritDocContainer (container, taglet));
+ }
+
+ private void postprocess_inheritdoc (DocumentationParser docparser) {
+ while (!this.inheritdocs.is_empty) {
- HashSet<string> processed = new HashSet<string> ();
++ InheritDocContainer container = this.inheritdocs.remove_at (0);
+
+ docparser.transform_inheritdoc (container.taglet_container, container.taglet);
+ }
+ }
+
+
+ /**
+ * Import documentation from various sources
+ *
+ * @param importers a list of importers
+ * @param packages sources
+ * @param import_directories List of directories where to find the files
+ */
+ public void import_comments (DocumentationImporter[] importers, string[] packages,
+ string[] import_directories)
+ {
++ Vala.HashSet<string> processed = new Vala.HashSet<string> ();
+ foreach (string pkg_name in packages) {
+ bool imported = false;
+ foreach (DocumentationImporter importer in importers) {
+ string? path = get_file_path ("%s.%s".printf (pkg_name, importer.file_extension),
+ import_directories);
+ if (path == null) {
+ continue;
+ }
+
+ path = realpath (path);
+ imported = true;
+
+ if (!processed.contains (path)) {
+ importer.process (path);
+ processed.add (path);
+ }
+ }
+
+ if (imported == false) {
+ reporter.simple_error (null, "'%s' not found in specified import directories", pkg_name);
+ }
+ }
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* typeparameter.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Content;
+
+ /**
+ * Represents a generic type parameter in the source code.
+ */
+ public class Valadoc.Api.TypeParameter : Symbol {
+
+ public TypeParameter (Node parent, SourceFile file, string name, void* data) {
+ base (parent, file, name, SymbolAccessibility.PUBLIC, data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ return new SignatureBuilder ()
+ .append_symbol (this)
+ .get ();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override NodeType node_type { get { return NodeType.TYPE_PARAMETER; } }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void accept (Visitor visitor) {
+ visitor.visit_type_parameter (this);
+ }
+
+ public override bool is_browsable (Settings settings) {
+ return false;
+ }
+
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* typereference.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private ArrayList<TypeReference> type_arguments = new ArrayList<TypeReference> ();
+
++using Valadoc.Content;
+
+ /**
+ * A reference to a data type.
+ */
+ public class Valadoc.Api.TypeReference : Item {
- public Gee.Collection<TypeReference> get_type_arguments () {
- return this.type_arguments.read_only_view;
++ private Vala.ArrayList<TypeReference> type_arguments = new Vala.ArrayList<TypeReference> ();
+ private string? dbus_type_signature;
+ private Ownership ownership;
+
+ public TypeReference (Item parent, Ownership ownership, bool pass_ownership, bool is_dynamic,
+ bool is_nullable, string? dbus_type_signature, void* data)
+ {
+ base (data);
+
+ this.dbus_type_signature = dbus_type_signature;
+ this.pass_ownership = pass_ownership;
+ this.is_nullable = is_nullable;
+ this.is_dynamic = is_dynamic;
+ this.ownership = ownership;
+ this.parent = parent;
+ }
+
+ /**
+ * Returns a copy of the list of generic type arguments.
+ *
+ * @return type argument list
+ */
++ public Vala.Collection<TypeReference> get_type_arguments () {
++ return this.type_arguments;
+ }
+
+ public void add_type_argument (TypeReference type_ref) {
+ type_arguments.add (type_ref);
+ }
+
+ /**
+ * The referred data type.
+ */
+ public Item? data_type {
+ set;
+ get;
+ }
+
+ public bool pass_ownership {
+ private set;
+ get;
+ }
+
+ /**
+ * Specifies that the expression is owned.
+ */
+ public bool is_owned {
+ get {
+ return ownership == Ownership.OWNED;
+ }
+ }
+
+ /**
+ * Specifies that the expression is weak.
+ */
+ public bool is_weak {
+ get {
+ return ownership == Ownership.WEAK;
+ }
+ }
+
+ /**
+ * Specifies that the expression is unwoned.
+ */
+ public bool is_unowned {
+ get {
+ return ownership == Ownership.UNOWNED;
+ }
+ }
+
+
+ /**
+ * Specifies that the expression is dynamic.
+ */
+ public bool is_dynamic {
+ private set;
+ get;
+ }
+
+ /**
+ * Specifies that the expression may be null.
+ */
+ public bool is_nullable {
+ private set;
+ get;
+ }
+
+ public string? get_dbus_type_signature () {
+ return dbus_type_signature;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected override Inline build_signature () {
+ var signature = new SignatureBuilder ();
+
+ if (is_dynamic) {
+ signature.append_keyword ("dynamic");
+ }
+
+ if (is_weak) {
+ signature.append_keyword ("weak");
+ } else if (is_owned) {
+ signature.append_keyword ("owned");
+ } else if (is_unowned) {
+ signature.append_keyword ("unowned");
+ }
+
+ if (data_type == null) {
+ signature.append_keyword ("void");
+ } else if (data_type is Symbol) {
+ signature.append_type ((Symbol) data_type);
+ } else {
+ signature.append_content (data_type.signature);
+ }
+
+ if (type_arguments.size > 0) {
+ signature.append ("<", false);
+ bool first = true;
+ foreach (Item param in type_arguments) {
+ if (!first) {
+ signature.append (",", false);
+ }
+ signature.append_content (param.signature, false);
+ first = false;
+ }
+ signature.append (">", false);
+ }
+
+ if (is_nullable) {
+ signature.append ("?", false);
+ }
+
+ return signature.get ();
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* typesymbol.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ /**
+ * Represents a runtime data type.
+ */
+ public abstract class Valadoc.Api.TypeSymbol : Symbol {
+ private SourceComment? source_comment;
+ private string? type_macro_name;
+ private string? is_type_macro_name;
+ private string? type_cast_macro_name;
+ private string? type_function_name;
+
+ public TypeSymbol (Node parent, SourceFile file, string name, SymbolAccessibility accessibility,
+ SourceComment? comment, string? type_macro_name, string? is_type_macro_name,
+ string? type_cast_macro_name, string? type_function_name, bool is_basic_type,
+ void* data)
+ {
+ base (parent, file, name, accessibility, data);
+
+ this.type_cast_macro_name = type_cast_macro_name;
+ this.is_type_macro_name = is_type_macro_name;
+ this.type_function_name = type_function_name;
+ this.type_macro_name = type_macro_name;
+
+ this.is_basic_type = is_basic_type;
+ this.source_comment = comment;
+ }
+
+ /**
+ * Specifies whether this symbol is a basic type (string, int, char, etc)
+ */
+ public bool is_basic_type {
+ private set;
+ get;
+ }
+
+ /**
+ * Gets the name of the GType macro which represents the type symbol
+ */
+ public string get_type_macro_name () {
+ return type_macro_name;
+ }
+
+ /**
+ * Gets the name of the GType macro which casts a type instance to the given type.
+ */
+ public string get_type_cast_macro_name () {
+ return type_cast_macro_name;
+ }
+
+ /**
+ * Gets the name of the GType macro which determines whether a type instance is of a given type.
+ */
+ public string get_is_type_macro_name () {
+ return is_type_macro_name;
+ }
+
+ /**
+ * Gets the name of the get_type() function which represents the type symbol
+ */
+ public string get_type_function_name () {
+ return type_function_name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void parse_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ return ;
+ }
+
+ if (source_comment != null) {
+ documentation = parser.parse (this, source_comment);
+ }
+
+ base.parse_comments (settings, parser);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ internal override void check_comments (Settings settings, DocumentationParser parser) {
+ if (documentation != null) {
+ parser.check (this, documentation);
+ }
+
+ base.check_comments (settings, parser);
+ }
+ }
--- /dev/null
- #if WITH_CGRAPH
+ /* chartfactory.vala
+ *
+ * Copyright (C) 2008 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ public abstract class Valadoc.Charts.Factory : Object {
+ protected Gvc.Node create_type (Gvc.Graph graph, Api.Node item) {
- #else
++#if WITH_CGRAPH
+ return graph.create_node (item.get_full_name (), 1);
- #endif
++#else
+ return graph.create_node (item.get_full_name ());
++#endif
+ }
+
+ public abstract Gvc.Graph create_graph (Api.Node item);
+
+ public abstract Gvc.Context create_context (Gvc.Graph graph);
+
+ public abstract Gvc.Node create_class (Gvc.Graph graph, Api.Class item);
+
+ public abstract Gvc.Node create_struct (Gvc.Graph graph, Api.Struct item);
+
+ public abstract Gvc.Node create_interface (Gvc.Graph graph, Api.Interface item);
+
+ public abstract Gvc.Node create_enum (Gvc.Graph graph, Api.Enum item);
+
+ public abstract Gvc.Node create_delegate (Gvc.Graph graph, Api.Delegate item);
+
+ public abstract Gvc.Node create_errordomain (Gvc.Graph graph, Api.ErrorDomain item);
+
+ public abstract Gvc.Node create_namespace (Gvc.Graph graph, Api.Namespace item);
+
+ public abstract Gvc.Edge add_children (Gvc.Graph graph, Gvc.Node parent, Gvc.Node child);
+ }
+
--- /dev/null
-using Gee;
-
+ /* hierarchychart.vala
+ *
+ * Copyright (C) 2008 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private void draw_implemented_interfaces (Gvc.Node child, Collection<Api.TypeReference> interfaces) {
+
+ public class Valadoc.Charts.Hierarchy : Charts.Chart {
+ public Hierarchy (Factory factory, Api.Node node) {
+ base (factory, node);
+ }
+
++ private void draw_implemented_interfaces (Gvc.Node child, Vala.Collection<Api.TypeReference> interfaces) {
+ foreach (Api.TypeReference typeref in interfaces) {
+ var parent = factory.create_interface (graph, (Api.Interface) typeref.data_type);
+ factory.add_children (graph, parent, child);
+ }
+ }
+
+ private void draw_parent_classes (Api.Class item, Gvc.Node? child = null) {
+ var parent = factory.create_class (graph, item);
+
+ if (child != null) {
+ factory.add_children (graph, parent, child);
+ }
+
+ if (item.base_type != null) {
+ draw_parent_classes ((Api.Class) item.base_type.data_type, parent);
+ }
+
+ draw_implemented_interfaces (parent, item.get_implemented_interface_list ());
+ }
+
+ private void draw_parent_structs (Api.Struct item, Gvc.Node? child = null) {
+ var parent = factory.create_struct (graph, item);
+
+ if (child != null) {
+ factory.add_children (graph, parent, child);
+ }
+
+ if (item.base_type != null) {
+ draw_parent_structs ((Api.Struct) item.base_type.data_type, parent);
+ }
+ }
+
+ public override void visit_interface (Api.Interface item) {
+ var iface = factory.create_interface (graph, item);
+
+ if (item.base_type != null) {
+ draw_parent_classes ((Api.Class) item.base_type.data_type, iface);
+ }
+
+ draw_implemented_interfaces (iface, item.get_implemented_interface_list ());
+ }
+
+ public override void visit_class (Api.Class item) {
+ draw_parent_classes (item);
+ }
+
+ public override void visit_struct (Api.Struct item) {
+ draw_parent_structs (item);
+ }
+ }
+
--- /dev/null
- #if WITH_CGRAPH
+ /* simplechartfactory.vala
+ *
+ * Copyright (C) 2008 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+
+ public class Valadoc.Charts.SimpleFactory : Charts.Factory {
+ protected virtual Gvc.Node configure_type (Gvc.Node node, Api.Node item) {
+ node.safe_set ("shape", "box", "");
+ node.safe_set ("fontname", "Times", "");
+ node.safe_set ("label", item.get_full_name (), "");
+ return node;
+ }
+
+ public override Gvc.Graph create_graph (Api.Node item) {
- #else
++#if WITH_CGRAPH
+ var graph = new Gvc.Graph (item.get_full_name (), Gvc.Agdirected, 0);
- #endif
++#else
+ var graph = new Gvc.Graph (item.get_full_name (), Gvc.GraphKind.AGDIGRAPH);
++#endif
+ return graph;
+ }
+
+ public override Gvc.Context create_context (Gvc.Graph graph) {
+ var context = new Gvc.Context ();
+ context.layout_jobs (graph);
+ context.layout (graph, "dot");
+ return context;
+ }
+
+ public override Gvc.Node create_class (Gvc.Graph graph, Api.Class item) {
+ var node = configure_type (create_type (graph, item), item);
+ node.safe_set ("style", "bold", "");
+ return node;
+ }
+
+ public override Gvc.Node create_struct (Gvc.Graph graph, Api.Struct item) {
+ var node = configure_type (create_type (graph, item), item);
+ node.safe_set ("style", "bold", "");
+ return node;
+ }
+
+ public override Gvc.Node create_interface (Gvc.Graph graph, Api.Interface item) {
+ return configure_type (create_type (graph, item), item);
+ }
+
+ public override Gvc.Node create_enum (Gvc.Graph graph, Api.Enum item) {
+ return configure_type (create_type (graph, item), item);
+ }
+
+ public override Gvc.Node create_delegate (Gvc.Graph graph, Api.Delegate item) {
+ return configure_type (create_type (graph, item), item);
+ }
+
+ public override Gvc.Node create_errordomain (Gvc.Graph graph, Api.ErrorDomain item) {
+ return configure_type (create_type (graph, item), item);
+ }
+
+ public override Gvc.Node create_namespace (Gvc.Graph graph, Api.Namespace item) {
+ return configure_type (create_type (graph, item), item);
+ }
+
+ public override Gvc.Edge add_children (Gvc.Graph graph, Gvc.Node parent, Gvc.Node child) {
+ var edge = graph.create_edge (parent, child);
+ edge.safe_set ("dir", "back", "");
+ return edge;
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* blockcontent.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- public Gee.List<Block> content { get { return _content; } }
+
+ public abstract class Valadoc.Content.BlockContent : ContentElement {
- private Gee.List<Block> _content;
++ public Vala.List<Block> content { get { return _content; } }
+
- _content = new ArrayList<Block> ();
++ private Vala.List<Block> _content;
+
+ construct {
++ _content = new Vala.ArrayList<Block> ();
+ }
+
+ internal BlockContent () {
+ }
+
+ public override void configure (Settings settings, ResourceLocator locator) {
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ foreach (Block element in _content) {
+ element.parent = this;
+ element.check (api_root, container, file_path, reporter, settings);
+ }
+ }
+
+ public override void accept_children (ContentVisitor visitor) {
+ foreach (Block element in _content) {
+ element.accept (visitor);
+ }
+ }
+
+ public override bool is_empty () {
+ foreach (Block item in content) {
+ if (!item.is_empty ()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
--- /dev/null
-using Valadoc.Taglets;
-using Gee;
+ /* comment.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- public Gee.List<Taglet> taglets { get { return _taglets; } }
- private Gee.List<Taglet> _taglets;
+
++using Valadoc.Taglets;
+
+ public class Valadoc.Content.Comment : BlockContent {
- _taglets = new ArrayList<Taglet> ();
++ public Vala.List<Taglet> taglets { get { return _taglets; } }
++ private Vala.List<Taglet> _taglets;
+
+ private bool checked = false;
+
+
+ internal Comment () {
+ base ();
- public Gee.List<Taglet> find_taglets (Api.Node? container, Type taglet_type) {
- Gee.List<Taglet> selected_taglets = new ArrayList<Taglet> ();
++ _taglets = new Vala.ArrayList<Taglet> ();
+ }
+
+ public override void configure (Settings settings, ResourceLocator locator) {
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ if (checked == true) {
+ return ;
+ }
+
+ checked = true;
+
+
+ base.check (api_root, container, file_path, reporter, settings);
+
+ foreach (Taglet element in _taglets) {
+ element.parent = this;
+ element.check (api_root, container, file_path, reporter, settings);
+ }
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_comment (this);
+ }
+
+ public override void accept_children (ContentVisitor visitor) {
+ base.accept_children (visitor);
+
+ foreach (Taglet element in _taglets) {
+ element.accept (visitor);
+ }
+ }
+
++ public Vala.List<Taglet> find_taglets (Api.Node? container, Type taglet_type) {
++ Vala.List<Taglet> selected_taglets = new Vala.ArrayList<Taglet> ();
+
+ // TODO inherit stuff if needed
+
+ foreach (Taglet taglet in _taglets) {
+ if (taglet.get_type () == taglet_type) {
+ selected_taglets.add (taglet);
+ }
+ }
+
+ return selected_taglets;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ assert (new_parent == null);
+
+ Comment comment = new Comment ();
+ comment.parent = new_parent;
+
+ foreach (Block element in content) {
+ Block copy = element.copy (comment) as Block;
+ comment.content.add (copy);
+ }
+
+ foreach (Taglet taglet in _taglets) {
+ Taglet copy = taglet.copy (comment) as Taglet;
+ comment.taglets.add (copy);
+ }
+
+ return comment;
+ }
+ }
+
--- /dev/null
-using GLib;
-
+ /* contentelement.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public abstract class Valadoc.Content.ContentElement : Object {
+ public ContentElement parent { get; internal set; }
+
+ public abstract ContentElement copy (ContentElement? new_parent = null);
+
+
+ public virtual void configure (Settings settings, ResourceLocator locator) {
+ }
+
+ public abstract void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings);
+
+ public abstract void accept (ContentVisitor visitor);
+
+ public abstract bool is_empty ();
+
+ public virtual void accept_children (ContentVisitor visitor) {
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* contentfactory.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.ContentFactory : Object {
+
+ public ContentFactory (Settings settings, ResourceLocator locator, ModuleLoader modules) {
+ _settings = settings;
+ _locator = locator;
+ _modules = modules;
+ }
+
+ private Settings _settings;
+ private ResourceLocator _locator;
+ private ModuleLoader _modules;
+
+ private inline ContentElement configure (ContentElement element) {
+ element.configure (_settings, _locator);
+ return element;
+ }
+
+ public Comment create_comment () {
+ return (Comment) configure (new Comment ());
+ }
+
+ public Embedded create_embedded () {
+ return (Embedded) configure (new Embedded ());
+ }
+
+ public Headline create_headline () {
+ return (Headline) configure (new Headline ());
+ }
+
+ public Link create_link () {
+ return (Link) configure (new Link ());
+ }
+
+ public WikiLink create_wiki_link () {
+ return (WikiLink) configure (new WikiLink ());
+ }
+
+ public List create_list () {
+ return (List) configure (new List ());
+ }
+
+ public ListItem create_list_item () {
+ return (ListItem) configure (new ListItem ());
+ }
+
+ public Page create_page () {
+ return (Page) configure (new Page ());
+ }
+
+ public Paragraph create_paragraph () {
+ return (Paragraph) configure (new Paragraph ());
+ }
+
+ public Warning create_warning () {
+ return (Warning) configure (new Warning ());
+ }
+ public Note create_note () {
+ return (Note) configure (new Note ());
+ }
+
+ public Run create_run (Run.Style style) {
+ return (Run) configure (new Run (style));
+ }
+
+ public SourceCode create_source_code () {
+ return (SourceCode) configure (new SourceCode ());
+ }
+
+ public Table create_table () {
+ return (Table) configure (new Table ());
+ }
+
+ public TableCell create_table_cell () {
+ return (TableCell) configure (new TableCell ());
+ }
+
+ public TableRow create_table_row () {
+ return (TableRow) configure (new TableRow ());
+ }
+
+ public Taglet? create_taglet (string name) {
+ return _modules.create_taglet (name);
+ }
+
+ public Text create_text (string? text = null) {
+ return (Text) configure (new Text (text));
+ }
+
+ public ContentElement set_style_attributes (StyleAttributes element,
+ VerticalAlign? valign,
+ HorizontalAlign? halign,
+ string? style) {
+ element.vertical_align = valign;
+ element.horizontal_align = halign;
+ element.style = style;
+ return element;
+ }
+ }
--- /dev/null
-using GLib;
-
+ /* contentrenderer.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public abstract class Valadoc.Content.ContentRenderer : ContentVisitor {
+
+ public abstract void render (ContentElement element);
+
+ public abstract void render_children (ContentElement element);
+ }
+
--- /dev/null
-using GLib;
-
+ /* contentvisitor.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public abstract class Valadoc.Content.ContentVisitor : Object {
+
+ public virtual void visit_comment (Comment element) {
+ }
+
+ public virtual void visit_embedded (Embedded element) {
+ }
+
+ public virtual void visit_headline (Headline element) {
+ }
+
+ public virtual void visit_link (Link element) {
+ }
+
+ public virtual void visit_wiki_link (WikiLink element) {
+ }
+
+ public virtual void visit_symbol_link (SymbolLink element) {
+ }
+
+ public virtual void visit_list (List element) {
+ }
+
+ public virtual void visit_list_item (ListItem element) {
+ }
+
+ public virtual void visit_paragraph (Paragraph element) {
+ }
+
+ public virtual void visit_warning (Warning element) {
+ }
+
+ public virtual void visit_note (Note element) {
+ }
+
+ public virtual void visit_page (Page element) {
+ }
+
+ public virtual void visit_run (Run element) {
+ }
+
+ public virtual void visit_source_code (SourceCode element) {
+ }
+
+ public virtual void visit_table (Table element) {
+ }
+
+ public virtual void visit_table_cell (TableCell element) {
+ }
+
+ public virtual void visit_table_row (TableRow element) {
+ }
+
+ public virtual void visit_taglet (Taglet element) {
+ }
+
+ public virtual void visit_text (Text element) {
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* embedded.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Embedded : ContentElement, Inline, StyleAttributes {
+ public string url {
+ get;
+ set;
+ }
+
+ public string? caption {
+ get;
+ set;
+ }
+
+ public HorizontalAlign? horizontal_align {
+ get;
+ set;
+ }
+
+ public VerticalAlign? vertical_align {
+ get;
+ set;
+ }
+
+ public string? style {
+ get;
+ set;
+ }
+
+ public Api.Package package;
+
+ private ResourceLocator _locator;
+
+ internal Embedded () {
+ base ();
+ }
+
+ public override void configure (Settings settings, ResourceLocator locator) {
+ _locator = locator;
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // search relative to our file
+ if (!Path.is_absolute (url)) {
+ string relative_to_file = Path.build_path (Path.DIR_SEPARATOR_S,
+ Path.get_dirname (file_path),
+ url);
+ if (FileUtils.test (relative_to_file, FileTest.EXISTS | FileTest.IS_REGULAR)) {
+ url = (owned) relative_to_file;
+ package = container.package;
+ return ;
+ }
+ }
+
+ // search relative to the current directory / absoulte path
+ if (!FileUtils.test (url, FileTest.EXISTS | FileTest.IS_REGULAR)) {
+ string base_name = Path.get_basename (url);
+
+ foreach (unowned string dir in settings.alternative_resource_dirs) {
+ string alternative_path = Path.build_path (Path.DIR_SEPARATOR_S,
+ dir,
+ base_name);
+ if (FileUtils.test (alternative_path, FileTest.EXISTS | FileTest.IS_REGULAR)) {
+ url = (owned) alternative_path;
+ package = container.package;
+ return ;
+ }
+ }
+
+ string node_segment = (container is Api.Package)? "" : container.get_full_name () + ": ";
+ reporter.simple_error ("%s: %s{{".printf (file_path, node_segment),
+ "'%s' does not exist", url);
+ } else {
+ package = container.package;
+ }
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_embedded (this);
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Embedded embedded = new Embedded ();
+ embedded.parent = new_parent;
+
+ embedded.horizontal_align = horizontal_align;
+ embedded.vertical_align = vertical_align;
+ embedded._locator = _locator;
+ embedded.caption = caption;
+ embedded.package = package;
+ embedded.style = style;
+ embedded.url = url;
+
+ return embedded;
+ }
+ }
--- /dev/null
-using Gee;
-
+ /* headline.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Headline : InlineContent, Block {
+ public int level { get; set; }
+
+ internal Headline () {
+ base ();
+ _level = 0;
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // TODO report error if level == 0 ?
+ // TODO: content.size == 0?
+
+ // Check inline content
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_headline (this);
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Headline headline = new Headline ();
+ headline.parent = new_parent;
+ headline.level = level;
+
+ foreach (Inline element in content) {
+ Inline copy = element.copy (headline) as Inline;
+ headline.content.add (copy);
+ }
+
+ return headline;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* inlinecontent.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- public Gee.List<Inline> content {
+
+ public abstract class Valadoc.Content.InlineContent : ContentElement {
- private Gee.List<Inline> _content;
++ public Vala.List<Inline> content {
+ get {
+ return _content;
+ }
+ }
+
- _content = new ArrayList<Inline> ();
++ private Vala.List<Inline> _content;
+
+ construct {
++ _content = new Vala.ArrayList<Inline> ();
+ }
+
+ internal InlineContent () {
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ foreach (Inline element in _content) {
+ element.parent = this;
+ element.check (api_root, container, file_path, reporter, settings);
+ }
+ }
+
+ public override void accept_children (ContentVisitor visitor) {
+ foreach (Inline element in _content) {
+ element.accept (visitor);
+ }
+ }
+
+ public override bool is_empty () {
+ foreach (Inline item in content) {
+ if (!item.is_empty ()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ internal void replace_node (Inline old, Inline replacement) {
+ int index = _content.index_of (old);
+ assert (index >= 0);
+
+ _content.set (index, replacement);
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* taglet.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public abstract class Valadoc.Content.InlineTaglet : ContentElement, Taglet, Inline {
+ protected Settings settings;
+ protected ResourceLocator locator;
+ private ContentElement _content;
+
+ public InlineTaglet () {
+ base ();
+ }
+
+ public abstract Rule? get_parser_rule (Rule run_rule);
+
+ public abstract ContentElement produce_content ();
+
+ private ContentElement get_content () {
+ if (_content == null) {
+ _content = produce_content ();
+ }
+ return _content;
+ }
+
+ public override void configure (Settings settings, ResourceLocator locator) {
+ this.settings = settings;
+ this.locator = locator;
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ ContentElement element = get_content ();
+ element.parent = this;
+
+ element.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ ContentElement element = get_content ();
+ element.accept (visitor);
+ }
+
+ public override bool is_empty () {
+ // taglets are not empty by default
+ return false;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* link.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Link : InlineContent, Inline {
+ public string url {
+ set;
+ get;
+ }
+
+ /**
+ * Used by importers to transform internal URLs
+ */
+ public Importer.InternalIdRegistrar id_registrar {
+ internal set;
+ get;
+ }
+
+
+ internal Link () {
+ base ();
+ }
+
+ public override void configure (Settings settings, ResourceLocator locator) {
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+
+ // Internal gktdoc-id? (gir-importer)
+ if (id_registrar != null) {
+ Api.Node? node = id_registrar.map_symbol_id (url);
+ if (node != null) {
+ InlineContent _parent = parent as InlineContent;
+ assert (_parent != null);
+
+ SymbolLink replacement = new SymbolLink (node);
+ replacement.content.add_all (content);
+
+ replacement.check (api_root, container, file_path, reporter, settings);
+ _parent.replace_node (this, replacement);
+ return ;
+ }
+
+
+ string _url = id_registrar.map_url_id (url);
+ if (_url == null) {
+ string node_segment = (container is Api.Package)? "" : container.get_full_name () + ": ";
+ reporter.simple_warning ("%s: %s[[".printf (file_path, node_segment),
+ "unknown imported internal id '%s'", url);
+
+ InlineContent _parent = parent as InlineContent;
+ assert (_parent != null);
+
+ Run replacement = new Run (Run.Style.ITALIC);
+ replacement.content.add_all (content);
+ replacement.check (api_root, container, file_path, reporter, settings);
+
+ _parent.replace_node (this, replacement);
+ return ;
+ }
+
+ url = _url;
+ }
+
+
+ //TODO: check url
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_link (this);
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Link link = new Link ();
+ link.id_registrar = id_registrar;
+ link.parent = new_parent;
+ link.url = url;
+
+ foreach (Inline element in content) {
+ Inline copy = element.copy (link) as Inline;
+ link.content.add (copy);
+ }
+
+ return link;
+ }
+ }
--- /dev/null
-using Gee;
-
+ /* list.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- public Gee.List<ListItem> items {
+
+ public class Valadoc.Content.List : ContentElement, Block {
+ public enum Bullet {
+ NONE,
+ UNORDERED,
+ ORDERED,
+ ORDERED_NUMBER,
+ ORDERED_LOWER_CASE_ALPHA,
+ ORDERED_UPPER_CASE_ALPHA,
+ ORDERED_LOWER_CASE_ROMAN,
+ ORDERED_UPPER_CASE_ROMAN;
+
+ public static Bullet? from_string (string? str) {
+ switch (str) {
+ case "none":
+ return Bullet.NONE;
+
+ case "unordered":
+ return Bullet.UNORDERED;
+
+ case "ordered":
+ return Bullet.ORDERED;
+
+ case "ordered-number":
+ return Bullet.ORDERED_NUMBER;
+
+ case "ordered-lower-case-alpa":
+ return Bullet.ORDERED_LOWER_CASE_ALPHA;
+
+ case "ordered-upper-case-alpha":
+ return Bullet.ORDERED_UPPER_CASE_ALPHA;
+
+ case "ordered-lower-case-roman":
+ return Bullet.ORDERED_LOWER_CASE_ROMAN;
+
+ case "ordered-upper-case-roman":
+ return Bullet.ORDERED_UPPER_CASE_ROMAN;
+ }
+
+ return null;
+ }
+
+ public unowned string to_string () {
+ switch (this) {
+ case Bullet.NONE:
+ return "none";
+
+ case Bullet.UNORDERED:
+ return "unordered";
+
+ case Bullet.ORDERED:
+ return "ordered";
+
+ case Bullet.ORDERED_NUMBER:
+ return "ordered-number";
+
+ case Bullet.ORDERED_LOWER_CASE_ALPHA:
+ return "ordered-lower-case-alpa";
+
+ case Bullet.ORDERED_UPPER_CASE_ALPHA:
+ return "ordered-upper-case-alpha";
+
+ case Bullet.ORDERED_LOWER_CASE_ROMAN:
+ return "ordered-lower-case-roman";
+
+ case Bullet.ORDERED_UPPER_CASE_ROMAN:
+ return "ordered-upper-case-roman";
+ }
+
+ assert (true);
+ return "";
+ }
+ }
+
+ public Bullet bullet {
+ get;
+ set;
+ }
+
+ // TODO add initial value (either a number or some letters)
- private Gee.List<ListItem> _items;
++ public Vala.List<ListItem> items {
+ get {
+ return _items;
+ }
+ }
+
- _items = new ArrayList<ListItem> ();
++ private Vala.List<ListItem> _items;
+
+ internal List () {
+ base ();
+ _bullet = Bullet.NONE;
++ _items = new Vala.ArrayList<ListItem> ();
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check individual list items
+ foreach (ListItem element in _items) {
+ element.parent = this;
+ element.check (api_root, container, file_path, reporter, settings);
+ }
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_list (this);
+ }
+
+ public override void accept_children (ContentVisitor visitor) {
+ foreach (ListItem element in _items) {
+ element.accept (visitor);
+ }
+ }
+
+ public override bool is_empty () {
+ return _items.size == 0;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Content.List list = new Content.List ();
+ list.parent = new_parent;
+ list.bullet = bullet;
+
+ foreach (ListItem item in items) {
+ ListItem copy = item.copy (list) as ListItem;
+ list.items.add (copy);
+ }
+
+ return list;
+ }
+ }
--- /dev/null
-using Gee;
-
+ /* listitem.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.ListItem : BlockContent {
+
+ internal ListItem () {
+ base ();
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check block content
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_list_item (this);
+ }
+
+ public override void accept_children (ContentVisitor visitor) {
+ base.accept_children (visitor);
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ ListItem item = new ListItem ();
+ item.parent = new_parent;
+
+ foreach (Block block in content) {
+ Block copy = block.copy (item) as Block;
+ item.content.add (copy);
+ }
+
+ return item;
+ }
+ }
--- /dev/null
-using Gee;
-
+ /* note.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Note : BlockContent, Block {
+ internal Note () {
+ base ();
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check inline content
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_note (this);
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Note note = new Note ();
+ note.parent = new_parent;
+
+ foreach (Block block in content) {
+ Block copy = block.copy (note) as Block;
+ note.content.add (copy);
+ }
+
+ return note;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* page.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Page : BlockContent {
+ private bool checked = false;
+
+
+ internal Page () {
+ base ();
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_page (this);
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ if (checked == true) {
+ return ;
+ }
+
+ checked = true;
+
+
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ assert (new_parent == null);
+
+ Content.Page page = new Content.Page ();
+ page.parent = new_parent;
+
+ foreach (Block block in content) {
+ Block copy = block.copy (page) as Block;
+ page.content.add (copy);
+ }
+
+ return page;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* paragraph.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Paragraph : InlineContent, Block, StyleAttributes {
+ public HorizontalAlign? horizontal_align {
+ get;
+ set;
+ }
+
+ public VerticalAlign? vertical_align {
+ get;
+ set;
+ }
+
+ public string? style {
+ get;
+ set;
+ }
+
+ internal Paragraph () {
+ base ();
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check inline content
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_paragraph (this);
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Paragraph p = new Paragraph ();
+ p.parent = new_parent;
+
+ p.horizontal_align = horizontal_align;
+ p.vertical_align = vertical_align;
+ p.style = style;
+
+ foreach (Inline element in content) {
+ Inline copy = element.copy (p) as Inline;
+ p.content.add (copy);
+ }
+
+ return p;
+ }
+ }
+
--- /dev/null
-using GLib;
-
+ /* resourcelocator.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public interface Valadoc.ResourceLocator : Object {
+ public abstract string resolve (string path);
+ }
+
--- /dev/null
-using Gee;
-
+ /* run.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Run : InlineContent, Inline {
+ public enum Style {
+ NONE,
+ BOLD,
+ ITALIC,
+ UNDERLINED,
+ MONOSPACED,
+ STROKE,
+ LANG_KEYWORD,
+ LANG_LITERAL,
+ LANG_BASIC_TYPE,
+ LANG_TYPE,
+ LANG_PREPROCESSOR,
+ LANG_COMMENT,
+ LANG_ESCAPE,
+
+ XML_ESCAPE,
+ XML_ELEMENT,
+ XML_ATTRIBUTE,
+ XML_ATTRIBUTE_VALUE,
+ XML_COMMENT,
+ XML_CDATA;
+
+ public static Style? from_string (string str) {
+ switch (str) {
+ case "none":
+ return Style.NONE;
+
+ case "bold":
+ return Style.BOLD;
+
+ case "italic":
+ return Style.ITALIC;
+
+ case "underlined":
+ return Style.UNDERLINED;
+
+ case "monospaced":
+ return Style.MONOSPACED;
+
+ case "stroke":
+ return Style.STROKE;
+
+ case "lang-escape":
+ return Style.LANG_ESCAPE;
+
+ case "lang-keyword":
+ return Style.LANG_KEYWORD;
+
+ case "lang-literal":
+ return Style.LANG_LITERAL;
+
+ case "lang-basic-type":
+ return Style.LANG_BASIC_TYPE;
+
+ case "lang-type":
+ return Style.LANG_TYPE;
+
+ case "lang-preprocessor":
+ return Style.LANG_PREPROCESSOR;
+
+ case "lang-comment":
+ return Style.LANG_COMMENT;
+
+ case "xml-escape":
+ return Style.XML_ESCAPE;
+
+ case "xml-element":
+ return Style.XML_ELEMENT;
+
+ case "xml-attribute":
+ return Style.XML_ATTRIBUTE;
+
+ case "xml-attribute-value":
+ return Style.XML_ATTRIBUTE_VALUE;
+
+ case "xml-comment":
+ return Style.XML_COMMENT;
+
+ case "xml-cdata":
+ return Style.XML_CDATA;
+ }
+
+ return null;
+ }
+
+ public unowned string to_string () {
+ switch (this) {
+ case Style.NONE:
+ return "none";
+
+ case Style.BOLD:
+ return "bold";
+
+ case Style.ITALIC:
+ return "italic";
+
+ case Style.UNDERLINED:
+ return "underlined";
+
+ case Style.MONOSPACED:
+ return "monospaced";
+
+ case Style.STROKE:
+ return "stroke";
+
+ case Style.LANG_ESCAPE:
+ return "lang-escape";
+
+ case Style.LANG_KEYWORD:
+ return "lang-keyword";
+
+ case Style.LANG_LITERAL:
+ return "lang-literal";
+
+ case Style.LANG_BASIC_TYPE:
+ return "lang-basic-type";
+
+ case Style.LANG_TYPE:
+ return "lang-type";
+
+ case Style.LANG_PREPROCESSOR:
+ return "lang-preprocessor";
+
+ case Style.LANG_COMMENT:
+ return "lang-comment";
+
+ case Style.XML_ESCAPE:
+ return "xml-escape";
+
+ case Style.XML_ELEMENT:
+ return "xml-element";
+
+ case Style.XML_ATTRIBUTE:
+ return "xml-attribute";
+
+ case Style.XML_ATTRIBUTE_VALUE:
+ return "xml-attribute-value";
+
+ case Style.XML_COMMENT:
+ return "xml-comment";
+
+ case Style.XML_CDATA:
+ return "xml-cdata";
+ }
+
+ assert (true);
+ return "";
+ }
+ }
+
+ public Style style { get; set; }
+
+ internal Run (Style style) {
+ base ();
+ _style = style;
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check inline content
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_run (this);
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Run run = new Run (style);
+ run.parent = new_parent;
+
+ foreach (Inline element in content) {
+ Inline copy = element.copy (run) as Inline;
+ run.content.add (copy);
+ }
+
+ return run;
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* sourcecode.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.SourceCode : ContentElement, Inline {
+ public enum Language {
+ GENIE,
+ VALA,
+ XML,
+ C;
+
+ public static Language? from_path (string path) {
+ int pos = path.last_index_of (".");
+ if (pos < 0) {
+ return null;
+ }
+
+ string ext = path.substring (pos + 1);
+ return from_string (ext, true);
+ }
+
+ public static Language? from_string (string str, bool is_extension = false) {
+ switch (str) {
+ case "genie":
+ if (is_extension) {
+ return null;
+ }
+ return Language.GENIE;
+
+ case "gs":
+ return Language.GENIE;
+
+ case "xml":
+ return Language.XML;
+
+ case "vala":
+ return Language.VALA;
+
+ case "c":
+ case "h":
+ return Language.C;
+ }
+
+ return null;
+ }
+
+ public unowned string to_string () {
+ switch (this) {
+ case Language.GENIE:
+ return "genie";
+
+ case Language.VALA:
+ return "vala";
+
+ case Language.XML:
+ return "xml";
+
+ case Language.C:
+ return "c";
+ }
+
+ assert (true);
+ return "";
+ }
+ }
+
+
+ public string code {
+ get;
+ set;
+ }
+
+ public Run? highlighted_code {
+ get;
+ private set;
+ }
+
+ public Language? language {
+ get;
+ set;
+ }
+
+ internal SourceCode () {
+ base ();
+ _language = Language.VALA;
+ }
+
+ private string? get_path (string path, Api.Node container, string source_file_path,
+ ErrorReporter reporter)
+ {
+ // search relative to our file
+ if (!Path.is_absolute (path)) {
+ string relative_to_file = Path.build_path (Path.DIR_SEPARATOR_S,
+ Path.get_dirname (source_file_path),
+ path);
+ if (FileUtils.test (relative_to_file, FileTest.EXISTS | FileTest.IS_REGULAR)) {
+ return (owned) relative_to_file;
+ }
+ }
+
+ // search relative to the current directory / absoulte path
+ if (!FileUtils.test (path, FileTest.EXISTS | FileTest.IS_REGULAR)) {
+ string node_segment = (container is Api.Package)? "" : container.get_full_name () + ": ";
+ code = "File '%s' does not exist".printf (path);
+ reporter.simple_warning ("%s: %s{{{".printf (source_file_path, node_segment),
+ "%s", code);
+ return null;
+ }
+
+ return path;
+ }
+
+ private void load_source_code (string _path, Api.Node container, string source_file_path,
+ ErrorReporter reporter)
+ {
+ string? path = get_path (_path, container, source_file_path, reporter);
+ if (path == null) {
+ return ;
+ }
+
+ try {
+ string content = null;
+ FileUtils.get_contents (path, out content);
+ _language = Language.from_path (path);
+ code = (owned) content;
+ } catch (FileError err) {
+ string node_segment = (container is Api.Package)? "" : container.get_full_name () + ": ";
+ reporter.simple_error ("%s: %s{{{".printf (source_file_path, node_segment),
+ "Can't read file '%s': %s", path, err.message);
+ }
+ }
+
+ private inline bool is_empty_string (string line) {
+ for (int i = 0; line[i] != '\0'; i++) {
+ if (line[i].isspace () == false) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private string strip_code (string code) {
+ string[] lines = code.split ("\n");
+ for (int i = lines.length - 1; i >= 0 && is_empty_string (lines[i]); i--) {
+ lines[i] = null;
+ }
+
+ string** _lines = lines;
+ for (int i = 0; lines[i] != null && is_empty_string (lines[i]); i++) {
+ _lines = &lines[i + 1];
+ }
+
+ return string.joinv ("\n", (string[]) _lines);
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ string[] splitted = code.split ("\n", 2);
+ if (splitted[0].strip () == "") {
+ code = splitted[1] ?? "";
+ } else if (splitted[0].has_prefix ("#!")) {
+ unowned string start = (string) (((char*) splitted[0]) + 2);
+ if (start.has_prefix ("include:")) {
+ start = (string) (((char*) start) + 8);
+ string path = start.strip ();
+ load_source_code (path, container, file_path, reporter);
+ } else {
+ string name = start._strip ().down ();
+ _language = Language.from_string (name);
+ code = splitted[1] ?? "";
+ if (_language == null && name != "none") {
+ string node_segment = (container is Api.Package)? "" : container.get_full_name () + ": ";
+ reporter.simple_warning ("%s: %s{{{".printf (file_path, node_segment),
+ "Unsupported programming language '%s'", name);
+ }
+ }
+ }
+
+ code = strip_code (code);
+
+ if (_language == Language.VALA) {
+ highlighted_code = api_root.highlighter.highlight_vala (code);
+ } else if (_language == Language.XML) {
+ highlighted_code = api_root.highlighter.highlight_xml (code);
+ } else if (_language == Language.C) {
+ highlighted_code = api_root.highlighter.highlight_c (code);
+ } else {
+ highlighted_code = new Run (Run.Style.MONOSPACED);
+ highlighted_code.content.add (new Text (code));
+ }
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_source_code (this);
+ }
+
+ public override void accept_children (ContentVisitor visitor) {
+ if (highlighted_code != null) {
+ highlighted_code.accept (visitor);
+ }
+ }
+
+ public override bool is_empty () {
+ // empty source blocks are visible as well
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ SourceCode source_code = new SourceCode ();
+ source_code.parent = new_parent;
+
+ source_code.language = language;
+ source_code.code = code;
+
+ return source_code;
+ }
+ }
--- /dev/null
-using Gee;
-
+ /* styleattributes.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public enum Valadoc.Content.HorizontalAlign {
+ LEFT,
+ RIGHT,
+ CENTER;
+
+ public static HorizontalAlign? from_string (string str) {
+ switch (str) {
+ case "left":
+ return HorizontalAlign.LEFT;
+
+ case "right":
+ return HorizontalAlign.RIGHT;
+
+ case "center":
+ return HorizontalAlign.CENTER;
+ }
+
+ return null;
+ }
+
+ public unowned string to_string () {
+ switch (this) {
+ case HorizontalAlign.LEFT:
+ return "left";
+
+ case HorizontalAlign.RIGHT:
+ return "right";
+
+ case HorizontalAlign.CENTER:
+ return "center";
+ }
+
+ assert (true);
+ return "";
+ }
+ }
+
+ public enum Valadoc.Content.VerticalAlign {
+ TOP,
+ MIDDLE,
+ BOTTOM;
+
+ public static VerticalAlign? from_string (string str) {
+ switch (str) {
+ case "top":
+ return VerticalAlign.TOP;
+
+ case "middle":
+ return VerticalAlign.MIDDLE;
+
+ case "bottom":
+ return VerticalAlign.BOTTOM;
+ }
+
+ return null;
+ }
+
+ public unowned string to_string () {
+ switch (this) {
+ case VerticalAlign.TOP:
+ return "top";
+
+ case VerticalAlign.MIDDLE:
+ return "middle";
+
+ case VerticalAlign.BOTTOM:
+ return "bottom";
+ }
+
+ assert (true);
+ return "";
+ }
+ }
+
+ public interface Valadoc.Content.StyleAttributes : ContentElement {
+ public abstract HorizontalAlign? horizontal_align {
+ get;
+ set;
+ }
+
+ public abstract VerticalAlign? vertical_align {
+ get;
+ set;
+ }
+
+ public abstract string? style {
+ get;
+ set;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* symbollink.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.SymbolLink : InlineContent, Inline {
+ public Api.Node symbol {
+ get;
+ set;
+ }
+
+ public string given_symbol_name {
+ get;
+ set;
+ }
+
+ internal SymbolLink (Api.Node? symbol = null, string? given_symbol_name = null) {
+ base ();
+ _symbol = symbol;
+ _given_symbol_name = given_symbol_name;
+ }
+
+ public override void configure (Settings settings, ResourceLocator locator) {
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_symbol_link (this);
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ SymbolLink link = new SymbolLink (symbol, _given_symbol_name);
+ link.parent = new_parent;
+
+ foreach (Inline element in content) {
+ Inline copy = element.copy (link) as Inline;
+ link.content.add (copy);
+ }
+
+ return link;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* table.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- public Gee.List<TableRow> rows {
+
+ public class Valadoc.Content.Table : ContentElement, Block {
- private Gee.List<TableRow> _rows;
++ public Vala.List<TableRow> rows {
+ get {
+ return _rows;
+ }
+ }
+
- _rows = new ArrayList<TableRow> ();
++ private Vala.List<TableRow> _rows;
+
+ internal Table () {
+ base ();
++ _rows = new Vala.ArrayList<TableRow> ();
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check the table consistency in term of row/column number
+
+ // Check individual rows
+ foreach (var row in _rows) {
+ row.parent = this;
+ row.check (api_root, container, file_path, reporter, settings);
+ }
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_table (this);
+ }
+
+ public override void accept_children (ContentVisitor visitor) {
+ foreach (TableRow element in _rows) {
+ element.accept (visitor);
+ }
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Table table = new Table ();
+ table.parent = new_parent;
+
+ foreach (var row in _rows) {
+ TableRow copy = row.copy (table) as TableRow;
+ table.rows.add (copy);
+ }
+
+ return table;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* tablecell.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.TableCell : InlineContent, StyleAttributes {
+ public HorizontalAlign? horizontal_align {
+ get;
+ set;
+ }
+
+ public VerticalAlign? vertical_align {
+ get;
+ set;
+ }
+
+ public string? style {
+ get;
+ set;
+ }
+
+ public int colspan {
+ get;
+ set;
+ }
+
+ public int rowspan {
+ get;
+ set;
+ }
+
+ internal TableCell () {
+ base ();
+ _colspan = 1;
+ _rowspan = 1;
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check inline content
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_table_cell (this);
+ }
+
+ public override bool is_empty () {
+ // empty cells are displayed as well
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ TableCell cell = new TableCell ();
+ cell.parent = new_parent;
+
+ cell.horizontal_align = horizontal_align;
+ cell.vertical_align = vertical_align;
+ cell.colspan = colspan;
+ cell.rowspan = rowspan;
+ cell.style = style;
+
+ foreach (Inline element in content) {
+ Inline copy = element.copy (cell) as Inline;
+ cell.content.add (copy);
+ }
+
+ return cell;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* tablerow.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- public Gee.List<TableCell> cells {
+
+ public class Valadoc.Content.TableRow : ContentElement {
- private Gee.List<TableCell> _cells;
++ public Vala.List<TableCell> cells {
+ get {
+ return _cells;
+ }
+ }
+
- _cells = new ArrayList<TableCell> ();
++ private Vala.List<TableCell> _cells;
+
+ internal TableRow () {
+ base ();
++ _cells = new Vala.ArrayList<TableCell> ();
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check individual cells
+ foreach (var cell in _cells) {
+ cell.parent = this;
+ cell.check (api_root, container, file_path, reporter, settings);
+ }
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_table_row (this);
+ }
+
+ public override void accept_children (ContentVisitor visitor) {
+ foreach (TableCell element in _cells) {
+ element.accept (visitor);
+ }
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ TableRow row = new TableRow ();
+ row.parent = new_parent;
+
+ foreach (TableCell cell in _cells) {
+ TableCell copy = cell.copy (row) as TableCell;
+ row.cells.add (copy);
+ }
+
+ return row;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* taglet.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- public virtual Gee.List<ContentElement>? get_inheritable_documentation () {
+
+ public interface Valadoc.Content.Taglet : ContentElement {
+
+ public abstract Rule? get_parser_rule (Rule run_rule);
+
++ public virtual Vala.List<ContentElement>? get_inheritable_documentation () {
+ return null;
+ }
+
+ public virtual bool inheritable (Taglet taglet) {
+ return false;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* text.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Text : ContentElement, Inline {
+ public string content {
+ get;
+ set;
+ }
+
+ construct {
+ _content = "";
+ }
+
+ internal Text (string? text = null) {
+ if (text != null) {
+ _content = text;
+ }
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_text (this);
+ }
+
+
+ public override bool is_empty () {
+ return content == "";
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Text text = new Text (content);
+ text.parent = new_parent;
+ return text;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* warning.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.Warning : BlockContent, Block {
+ internal Warning () {
+ base ();
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check inline content
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_warning (this);
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Warning warning = new Warning ();
+ warning.parent = new_parent;
+
+ foreach (Block block in content) {
+ Block copy = block.copy (warning) as Block;
+ warning.content.add (copy);
+ }
+
+ return warning;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* link.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Content.WikiLink : InlineContent, Inline {
+ public WikiPage page {
+ internal set;
+ get;
+ }
+
+ public string name {
+ get;
+ set;
+ }
+
+ internal WikiLink () {
+ base ();
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ base.check (api_root, container, file_path, reporter, settings);
+
+ page = api_root.wikitree.search (name);
+ if (page == null) {
+ string node_segment = (container is Api.Package)? "" : container.get_full_name () + ": ";
+ reporter.simple_warning ("%s: %s[[".printf (file_path, node_segment),
+ "'%s' does not exist", name);
+ return ;
+ }
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_wiki_link (this);
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ WikiLink link = new WikiLink ();
+ link.parent = new_parent;
+
+ link.page = page;
+ link.name = name;
+
+ foreach (Inline element in content) {
+ Inline copy = element.copy (link) as Inline;
+ link.content.add (copy);
+ }
+
+ return link;
+ }
+ }
--- /dev/null
-using Valadoc.Api;
-using Gee;
+ /* ctyperesolver.vala
+ *
+ * Copyright (C) 2010 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private Map<string, Api.TypeSymbol> types = new HashMap<string, Api.TypeSymbol> ();
- private Map<string, Api.Node> nodes = new HashMap<string, Api.Node> ();
+
++using Valadoc.Api;
+
+ /**
+ * Resolves symbols by C-names
+ */
+ public class Valadoc.CTypeResolver : Visitor {
- Collection<Interface> interfaces = null;
- Collection<Class> classes = null;
++ private Vala.Map<string, Api.TypeSymbol> types = new Vala.HashMap<string, Api.TypeSymbol> (str_hash, str_equal);
++ private Vala.Map<string, Api.Node> nodes = new Vala.HashMap<string, Api.Node> (str_hash, str_equal);
+ private Api.Tree tree;
+
+ public CTypeResolver (Api.Tree tree) {
+ tree.accept (this);
+ this.tree = tree;
+ }
+
+ private string convert_array_to_camelcase (string[] elements) {
+ StringBuilder builder = new StringBuilder ();
+
+ foreach (string element in elements) {
+ builder.append_c (((char[])element)[0].toupper ());
+ builder.append (element.next_char ().down ());
+ }
+
+ return (owned) builder.str;
+ }
+
+ private bool is_capitalized_and_underscored (string name) {
+ unowned string pos;
+
+ unichar c = name.get_char ();
+
+
+ if (c < 'A' || c > 'Z') {
+ return false;
+ }
+
+ bool last_was_underscore = false;
+ for (c = (pos = name).get_char (); c != '\0' ; c = (pos = pos.next_char ()).get_char ()) {
+ if ((c != '_' && !(c >= 'A' && c <= 'Z')) || (last_was_underscore && c == '_')) {
+ return false;
+ }
+
+ last_was_underscore = (c == '_');
+ }
+
+ return !last_was_underscore;
+ }
+
+ private string? translate_cname_to_g (string name) {
+ if (is_capitalized_and_underscored (name)) {
+ string[] segments = name.split ("_");
+ unowned string last_segment = segments[segments.length - 1];
+ if (last_segment != "ERROR") {
+ return null;
+ }
+
+ return convert_array_to_camelcase (segments);
+ }
+
+ int length = name.length;
+ if (length > 5 && name.has_suffix ("Iface")) {
+ return name.substring (0, length - 5);
+ } else if (length > 5 && name.has_suffix ("Class")) {
+ return name.substring (0, length - 5);
+ }
+
+ return null;
+ }
+
+ public Api.TypeSymbol? resolve_symbol_type (string name) {
+ TypeSymbol? symbol = types.get (name);
+ if (symbol != null) {
+ return symbol;
+ }
+
+ if (is_capitalized_and_underscored (name)) {
+ string[] segments = name.split ("_");
+
+ if (segments[segments.length - 1] == "TYPE") {
+ segments.resize (segments.length - 1);
+ return types.get (convert_array_to_camelcase (segments));
+ } else if (segments.length > 2 && segments[1] == "TYPE") {
+ string[] _segments = segments[1:segments.length];
+ _segments[0] = segments[0];
+ return types.get (convert_array_to_camelcase (_segments));
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Resolves symbols by C-names
+ *
+ * @param _name a C-name
+ * @return the resolved node or null
+ */
+ public Api.Node? resolve_symbol (Api.Node? element, string _name) {
+ string name = _name.replace ("->", ".").replace ("-", "_");
+
+ if (element != null && name.has_prefix (":")) {
+ Item parent = element;
+ while (parent != null && !(parent is Class || parent is Interface)) {
+ parent = parent.parent;
+ }
+
+ if (parent is Class && ((Class) parent).get_cname () != null) {
+ name = ((Class) parent).get_cname () + name;
+ } else if (parent is Interface && ((Interface) parent).get_cname () != null) {
+ name = ((Interface) parent).get_cname () + name;
+ } else {
+ return null;
+ }
+
+ }
+
+ Api.Node? node = nodes.get (name);
+ if (node != null) {
+ return node;
+ }
+
+ string? alternative = translate_cname_to_g (name);
+ if (alternative != null) {
+ return nodes.get (alternative);
+ }
+
+ if (element != null && name.has_prefix (":")) {
+ if (element is Class && ((Class) element).get_cname () != null) {
+ return nodes.get (((Class) element).get_cname () + "." + name);
+ } else if (element is Struct && ((Struct) element).get_cname () != null) {
+ return nodes.get (((Struct) element).get_cname () + "." + name);
+ }
+ }
+
+ if (name == "dgettext") {
+ return nodes.get ("g_dgettext");
+ } else if (name == "printf") {
+ return this.tree.search_symbol_str (null, "GLib.FileStream.printf");
+ }
+
+ int dotpos = name.index_of_char ('.');
+ if (dotpos > 0) {
+ string fst = name.substring (0, dotpos);
+ string snd = name.substring (dotpos + 1);
+ return nodes.get (fst + ":" + snd);
+ }
+
+ return null;
+ }
+
+ private void register_symbol_type (string? name, Api.TypeSymbol symbol) {
+ if (name != null) {
+ types.set (name, symbol);
+ }
+ }
+
+ private void register_symbol (string? name, Api.Node node) {
+ if (name != null) {
+ nodes.set (name.replace ("-", "_"), node);
+ }
+ }
+
+ private string? get_parent_type_cname (Item item) {
+ string parent_cname = null;
+ if (item.parent is Class) {
+ parent_cname = ((Class) item.parent).get_cname ();
+ } else if (item.parent is Interface) {
+ parent_cname = ((Interface) item.parent).get_cname ();
+ } else if (item.parent is Struct) {
+ parent_cname = ((Struct) item.parent).get_cname ();
+ } else if (item.parent is ErrorDomain) {
+ parent_cname = ((ErrorDomain) item.parent).get_cname ();
+ } else if (item.parent is Api.Enum) {
+ parent_cname = ((Api.Enum) item.parent).get_cname ();
+ } else {
+ assert (true);
+ }
+ return parent_cname;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_tree (Api.Tree item) {
+ item.accept_children (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_package (Package item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_namespace (Namespace item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_interface (Interface item) {
+ register_symbol (item.get_cname (), item);
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_class (Class item) {
+ register_symbol_type (item.get_type_id (), item);
+ register_symbol (item.get_cname (), item);
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_struct (Struct item) {
+ register_symbol_type (item.get_type_id (), item);
+ register_symbol (item.get_cname (), item);
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_property (Property item) {
+ string parent_cname = get_parent_type_cname (item);
+ assert (parent_cname != null);
+
+ string cname = item.get_cname ();
+ register_symbol (parent_cname+":"+cname, item);
+
+
- Collection<Interface> interfaces = null;
- Collection<Class> classes = null;
++ Vala.Collection<Interface> interfaces = null;
++ Vala.Collection<Class> classes = null;
+
+ if (item.parent is Interface) {
+ interfaces = ((Api.Interface) item.parent).get_known_related_interfaces ();
+ classes = ((Api.Interface) item.parent).get_known_implementations ();
+ } else if (item.parent is Class) {
+ interfaces = ((Api.Class) item.parent).get_known_derived_interfaces ();
+ classes = ((Api.Class) item.parent).get_known_child_classes ();
+ }
+
+ foreach (Interface iface in interfaces) {
+ register_symbol (iface.get_cname () + ":" + cname, item);
+ }
+
+ foreach (Class cl in classes) {
+ register_symbol (cl.get_cname () + ":" + cname, item);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_field (Field item) {
+ if (item.parent is Namespace || item.is_static) {
+ register_symbol (item.get_cname (), item);
+ } else {
+ string parent_cname = get_parent_type_cname (item);
+ if (parent_cname != null) {
+ register_symbol (parent_cname + "." + item.get_cname (), item);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_constant (Constant item) {
+ register_symbol (item.get_cname (), item);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_delegate (Delegate item) {
+ register_symbol (item.get_cname (), item);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_signal (Api.Signal item) {
+ string parent_cname = get_parent_type_cname (item);
+ assert (parent_cname != null);
+
+ string? default_impl_cname = item.get_default_impl_cname ();
+ string cname = item.get_cname ();
+ register_symbol (parent_cname+"::"+cname, item);
+
+ if (item.is_virtual) {
+ // only supported by classes
+ register_symbol (parent_cname + "Class." + item.name, item);
+ }
+
++ Vala.Collection<Interface> interfaces = null;
++ Vala.Collection<Class> classes = null;
+
+ if (item.parent is Interface) {
+ interfaces = ((Api.Interface) item.parent).get_known_related_interfaces ();
+ classes = ((Api.Interface) item.parent).get_known_implementations ();
+ } else if (item.parent is Class) {
+ interfaces = ((Api.Class) item.parent).get_known_derived_interfaces ();
+ classes = ((Api.Class) item.parent).get_known_child_classes ();
+ }
+
+ foreach (Interface iface in interfaces) {
+ register_symbol (iface.get_cname () + "::" + cname, item);
+ }
+
+ foreach (Class cl in classes) {
+ register_symbol (cl.get_cname () + "::" + cname, item);
+ }
+
+ if (default_impl_cname != null) {
+ register_symbol (default_impl_cname, item);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_method (Method item) {
+ if (item.is_abstract || item.is_virtual || item.is_override) {
+ string parent_cname = get_parent_type_cname (item);
+
+ if (item.parent is Class) {
+ register_symbol (parent_cname + "Class." + item.name, item);
+ } else {
+ register_symbol (parent_cname + "Iface." + item.name, item);
+ }
+
+ // Allow to resolve invalid links:
+ register_symbol (parent_cname + "." + item.name, item);
+ }
+
+ register_symbol (item.get_cname (), item);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_error_domain (ErrorDomain item) {
+ register_symbol (item.get_cname (), item);
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_error_code (ErrorCode item) {
+ register_symbol (item.get_cname (), item);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_enum (Api.Enum item) {
+ register_symbol (item.get_cname (), item);
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_enum_value (Api.EnumValue item) {
+ register_symbol (item.get_cname (), item);
+ }
+ }
+
+
--- /dev/null
+ /* devhelp-markupwriter.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
++
+ public class Valadoc.Devhelp.MarkupWriter : Valadoc.MarkupWriter {
+
+ public MarkupWriter (FileStream stream, bool xml_declaration = true) {
+ // avoid broken implicit copy
+ unowned FileStream _stream = stream;
+
+ base ((str) => { _stream.printf (str); }, xml_declaration);
+ }
+
+ protected override bool inline_element (string name) {
+ return name != "book";
+ }
+
+ protected override bool content_inline_element (string name) {
+ return name == "keyword"
+ || name == "sub";
+ }
+
+ public MarkupWriter start_book (string title, string lang, string link, string name, string version, string author) {
+ this.start_tag ("book", {"xmlns", "http://www.devhelp.net/book",
+ "title", title,
+ "language", lang,
+ "name", name,
+ "version", version,
+ "author", author,
+ "link", link});
+ return this;
+ }
+
+ public MarkupWriter end_book () {
+ this.end_tag ("book");
+ return this;
+ }
+
+ public MarkupWriter start_functions () {
+ this.start_tag ("functions");
+ return this;
+ }
+
+ public MarkupWriter end_functions () {
+ this.end_tag ("functions");
+ return this;
+ }
+
+ public MarkupWriter start_chapters () {
+ this.start_tag ("chapters");
+ return this;
+ }
+
+ public MarkupWriter end_chapters () {
+ this.end_tag ("chapters");
+ return this;
+ }
+
+ public MarkupWriter start_sub (string name, string link) {
+ this.start_tag ("sub", {"name", name, "link", link});
+ return this;
+ }
+
+ public MarkupWriter end_sub () {
+ this.end_tag ("sub");
+ return this;
+ }
+
+ public MarkupWriter keyword (string name, string type, string link) {
+ this.start_tag ("keyword", {"type", type, "name", name, "link", link});
+ this.end_tag ("keyword");
+ return this;
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* doclet.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Brosch Florian <flo.brosch@gmail.com>
+ */
+
+
+ /**
+ * A plugin register function for doclets
+ *
+ * @see ModuleLoader
+ */
+ [CCode (has_target = false)]
+ public delegate Type Valadoc.DocletRegisterFunction (ModuleLoader module_loader);
+
+
+
+ /**
+ * Provides a mechanism to inspect the API & documentation of programs and libraries
+ */
+ public interface Valadoc.Doclet : GLib.Object {
+
+ /**
+ * Allows the doclet to inspect the given {@link Api.Tree}
+ *
+ * @param settings various configurations
+ * @param tree the tree to inspect
+ * @param reporter the reporter to use
+ * @see Content.ContentVisitor
+ * @see Api.Visitor
+ */
+ public abstract void process (Settings settings, Api.Tree tree, ErrorReporter reporter);
+ }
+
+
--- /dev/null
-using Gee;
+ /* documentation.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ public interface Valadoc.Documentation : Object {
+
+ /**
+ * The corresponding package
+ */
+ public abstract Api.Package? package {
+ get;
+ }
+
+ /**
+ * The corresponding file name
+ */
+ public abstract string? get_filename ();
+ }
+
--- /dev/null
-using Gee;
-
+ /* documentationparser.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
++
+ using Valadoc.Content;
+ using Valadoc.Importer;
- private HashMap<Api.SourceFile, GirMetaData> metadata;
+
+ public class Valadoc.DocumentationParser : Object, ResourceLocator {
- metadata = new HashMap<Api.SourceFile, GirMetaData> ();
++ private Vala.HashMap<Api.SourceFile, GirMetaData> metadata;
+ private Importer.InternalIdRegistrar id_registrar;
+
+
+ public DocumentationParser (Settings settings, ErrorReporter reporter,
+ Api.Tree tree, ModuleLoader modules)
+ {
+ _settings = settings;
+ _reporter = reporter;
+ _tree = tree;
+ _modules = modules;
+
+ _factory = new ContentFactory (_settings, this, _modules);
+
+ _wiki_scanner = new WikiScanner (_settings);
+ _wiki_parser = new Parser (_settings, _wiki_scanner, _reporter);
+ _wiki_scanner.set_parser (_wiki_parser);
+
+ _comment_scanner = new CommentScanner (_settings);
+ _comment_parser = new Parser (_settings, _comment_scanner, _reporter);
+ _comment_scanner.set_parser (_comment_parser);
+
+ gtkdoc_parser = new Gtkdoc.Parser (settings, reporter, tree, modules);
+ gtkdoc_markdown_parser = new Gtkdoc.MarkdownParser (settings, reporter, tree, modules);
+
+
- private ArrayList<Object> _stack = new ArrayList<Object> ();
++ metadata = new Vala.HashMap<Api.SourceFile, GirMetaData> ();
+ id_registrar = new Importer.InternalIdRegistrar ();
+
+ init_valadoc_rules ();
+ }
+
+ private Gtkdoc.Parser gtkdoc_parser;
+ private Gtkdoc.MarkdownParser gtkdoc_markdown_parser;
+
+ private Settings _settings;
+ private ErrorReporter _reporter;
+ private Api.Tree _tree;
+ private ModuleLoader _modules;
+
+ private ContentFactory _factory;
+ private WikiScanner _wiki_scanner;
+ private CommentScanner _comment_scanner;
+ private Parser _wiki_parser;
+ private Parser _comment_parser;
+
+ private Parser _parser;
+ private Scanner _scanner;
+
+ public Comment? parse (Api.Node element, Api.SourceComment comment) {
+ if (comment is Api.GirSourceComment) {
+ Api.GirSourceComment gir_comment = (Api.GirSourceComment) comment;
+ GirMetaData metadata = get_metadata_for_comment (gir_comment);
+
+ if (metadata.is_docbook) {
+ Comment doc_comment = gtkdoc_parser.parse (element, gir_comment, metadata, id_registrar);
+ return doc_comment;
+ } else {
+ Comment doc_comment = gtkdoc_markdown_parser.parse (element, gir_comment, metadata, id_registrar);
+ return doc_comment;
+ }
+ } else {
+ return parse_comment_str (element, comment.content, comment.file.get_name (),
+ comment.first_line, comment.first_column);
+ }
+ }
+
+ public Comment? parse_comment_str (Api.Node element, string content, string filename,
+ int first_line, int first_column)
+ {
+ try {
+ Comment doc_comment = parse_comment (content, filename, first_line, first_column);
+ return doc_comment;
+ } catch (ParserError error) {
+ return null;
+ }
+ }
+
+ public Page? parse_wikipage (Api.Package pkg, WikiPage page) {
+ if (page.documentation != null) {
+ return page.documentation;
+ }
+
+ if (page.documentation_str == null) {
+ return null;
+ }
+
+ try {
+ Page documentation = parse_wiki (page.documentation_str, page.get_filename ());
+ return documentation;
+ } catch (ParserError error) {
+ return null;
+ }
+ }
+
+ private Comment parse_comment (string content, string filename, int first_line, int first_column)
+ throws ParserError
+ {
+ _parser = _comment_parser;
+ _scanner = _comment_scanner;
+ _stack.clear ();
+ _comment_parser.parse (content, filename, first_line, first_column);
+ return (Comment) pop ();
+ }
+
+ private Page parse_wiki (string content, string filename) throws ParserError {
+ _parser = _wiki_parser;
+ _scanner = _wiki_scanner;
+ _stack.clear ();
+ _wiki_parser.parse (content, filename, 0, 0);
+ return (Page) pop ();
+ }
+
+ public void check (Api.Node element, Comment comment) {
+ comment.check (_tree, element, element.get_source_file ().relative_path, _reporter, _settings);
+ }
+
+ public void check_wikipage (Api.Package package, WikiPage page) {
+ page.documentation.check (_tree, package, page.path, _reporter, _settings);
+ }
+
+ public void transform_inheritdoc (Api.Node taglet_owner, Taglets.InheritDoc taglet) {
+ if (taglet.inherited == null) {
+ return ;
+ }
+
+
+ taglet.inherited.parse_comments (_settings, this);
+ if (taglet.inherited.documentation == null) {
+ return ;
+ }
+
+
+ taglet.inherited.check_comments (_settings, this);
+
+ taglet.transform (_tree, taglet_owner, taglet_owner.get_source_file ().get_name (), _reporter, _settings);
+ }
+
+ private GirMetaData get_metadata_for_comment (Api.GirSourceComment gir_comment) {
+ GirMetaData metadata = metadata.get (gir_comment.file);
+ if (metadata != null) {
+ return metadata;
+ }
+
+ metadata = new GirMetaData (gir_comment.file.relative_path, _settings.metadata_directories, _reporter);
+ if (metadata.index_sgml != null) {
+ id_registrar.read_index_sgml_file (metadata.index_sgml, metadata.index_sgml_online, _reporter);
+ }
+
+ this.metadata.set (gir_comment.file, metadata);
+ return metadata;
+ }
+
+ public string resolve (string path) {
+ return path;
+ }
+
++ private Vala.ArrayList<Object> _stack = new Vala.ArrayList<Object> ();
+
+ private void push (Object element) {
+ _stack.add (element);
+ }
+
+ private Object peek (int offset = -1) {
+ assert (_stack.size >= - offset);
+ return _stack.get (_stack.size + offset);
+ }
+
+ private Object pop () {
+ Object node = peek ();
+ _stack.remove_at (_stack.size - 1);
+ return node;
+ }
+
+ private Rule multiline_block_run;
+ private Rule multiline_run;
+ private int current_level = 0;
+ private int[] levels = new int[0];
+
+ private void new_list_item (Content.List.Bullet bullet) throws ParserError {
+ var new_item = _factory.create_list_item ();
+
+ Content.List list = null;
+ if (levels.length >= 1) {
+ if (current_level > levels[levels.length - 1]) {
+ list = _factory.create_list ();
+ list.bullet = bullet;
+
+ var current_item = peek () as ListItem;
+ current_item.content.add (list);
+ push (list);
+
+ levels += current_level;
+ } else {
+ bool poped_some_lists = false;
+ while (current_level < levels[levels.length - 1]) {
+ // Pop current item and list
+ pop ();
+ pop ();
+ levels.resize (levels.length - 1);
+ poped_some_lists = true;
+ }
+ list = peek (-2) as Content.List;
+
+ if (!poped_some_lists && bullet == Content.List.Bullet.NONE) {
+ ((Paragraph) ((ListItem) peek ()).content[0]).content.add (_factory.create_text (" "));
+ return;
+ } else if (list.bullet != bullet) {
+ _parser.error (null, "Invalid bullet type '%s': expected '%s'"
+ .printf (bullet_type_string (bullet), bullet_type_string (list.bullet)));
+ return;
+ }
+
+ pop ();
+ }
+ } else {
+ list = _factory.create_list ();
+ list.bullet = bullet;
+
+ ((BlockContent) peek ()).content.add (list);
+ push (list);
+
+ levels = new int[0];
+ levels += current_level;
+ }
+
+ list.items.add (new_item);
+ push (new_item);
+ }
+
+ private string bullet_type_string (Content.List.Bullet bullet) {
+ switch (bullet) {
+ case Content.List.Bullet.NONE:
+ return ".";
+ case Content.List.Bullet.UNORDERED:
+ return "*";
+ case Content.List.Bullet.ORDERED_NUMBER:
+ return "1.";
+ case Content.List.Bullet.ORDERED_LOWER_CASE_ALPHA:
+ return "a.";
+ case Content.List.Bullet.ORDERED_UPPER_CASE_ALPHA:
+ return "A.";
+ case Content.List.Bullet.ORDERED_LOWER_CASE_ROMAN:
+ return "i.";
+ case Content.List.Bullet.ORDERED_UPPER_CASE_ROMAN:
+ return "I.";
+ }
+ return "";
+ }
+
+ private void finish_list () {
+ while (peek () is ListItem) {
+ pop ();
+ pop ();
+ levels.resize (levels.length - 1);
+ }
+ }
+
+ private void add_content_string (string str) {
+ var text = peek () as Text;
+ if (text == null) {
+ push (text = _factory.create_text ());
+ }
+ text.content += str;
+ }
+
+ private void add_content_space () {
+ // avoid double spaces
+ var head = peek ();
+ Text text_node = null;
+
+ if (head is Text) {
+ text_node = (Text) head;
+ } else if (head is InlineContent && ((InlineContent) head).content.size > 0
+ && ((InlineContent) head).content.last () is Text)
+ {
+ text_node = (Text) ((InlineContent) head).content.last ();
+ } else {
+ text_node = _factory.create_text ();
+ ((InlineContent) peek ()).content.add (text_node);
+ }
+
+ if (!text_node.content.has_suffix (" ")) {
+ text_node.content += " ";
+ }
+ }
+
+ private void init_valadoc_rules () {
+ // Inline rules
+
+ StubRule run = new StubRule ();
+ run.set_name ("Run");
+
+ TokenType.Action add_text = (token) => {
+ add_content_string (token.to_string ());
+ };
+
+ TokenType space = TokenType.SPACE.action ((token) => { add_content_space (); });
+ TokenType word = TokenType.any_word ().action (add_text);
+
+ Rule optional_invisible_spaces =
+ Rule.option ({
+ Rule.many ({ TokenType.SPACE })
+ });
+
+ Rule optional_spaces =
+ Rule.option ({
+ Rule.many ({
+ TokenType.SPACE.action ((token) => { add_content_space (); })
+ })
+ });
+
+
+ Rule text =
+ Rule.many ({
+ Rule.one_of ({
+ TokenType.BREAK.action ((token) => { add_content_string ("\n"); }),
+ TokenType.CLOSED_BRACE.action (add_text),
+ TokenType.MINUS.action (add_text),
+ TokenType.ALIGN_BOTTOM.action (add_text),
+ TokenType.ALIGN_TOP.action (add_text),
+ TokenType.GREATER_THAN.action (add_text),
+ TokenType.LESS_THAN.action (add_text),
+ TokenType.DOUBLE_PIPE.action (add_text),
+ TokenType.PIPE.action (add_text),
+ TokenType.ALIGN_RIGHT.action (add_text),
+ TokenType.ALIGN_CENTER.action (add_text),
+ TokenType.EQUAL_1.action (add_text),
+ TokenType.EQUAL_2.action (add_text),
+ TokenType.EQUAL_3.action (add_text),
+ TokenType.EQUAL_4.action (add_text),
+ TokenType.EQUAL_5.action (add_text),
+ word
+ }),
+ Rule.option ({ space })
+ })
+ .set_name ("Text")
+ .set_start (() => { push (_factory.create_text ()); });
+
+ Rule run_with_spaces =
+ Rule.seq ({
+ Rule.many ({
+ Rule.one_of ({
+ optional_invisible_spaces,
+ run
+ })
+ })
+ })
+ .set_name ("RunWithSpaces");
+
+ multiline_run = Rule.many ({
+ run_with_spaces,
+ TokenType.EOL.action (() => { add_content_space (); })
+ })
+ .set_name ("MultiLineRun");
+
+ Rule inline_taglet =
+ Rule.seq ({
+ TokenType.OPEN_BRACE,
+ Rule.option ({
+ TokenType.AROBASE,
+ TokenType.any_word ().action ((token) => {
+ var taglet = _factory.create_taglet (token.to_string ());
+ if (!(taglet is Inline)) {
+ _parser.error (null, "Invalid taglet in this context: %s".printf (token.to_string ()));
+ }
+ push (taglet);
+ Rule? taglet_rule = taglet.get_parser_rule (multiline_run);
+ if (taglet_rule != null) {
+ _parser.push_rule (Rule.seq ({ TokenType.SPACE, taglet_rule }));
+ }
+ }),
+ TokenType.CLOSED_BRACE
+ })
+ .set_skip (() => { add_content_string ("{"); })
+ })
+ .set_name ("InlineTaglet");
+
+ //TODO: Find a nicer way to allow empty tags (''run?'' won't work)
+ Rule bold =
+ Rule.seq ({
+ TokenType.SINGLE_QUOTE_2,
+ Rule.one_of ({
+ TokenType.SINGLE_QUOTE_2,
+ Rule.seq ({ optional_spaces, run, TokenType.SINGLE_QUOTE_2 })
+ })
+ })
+ .set_name ("Bold")
+ .set_start (() => { push (_factory.create_run (Run.Style.BOLD)); });
+
+ Rule italic =
+ Rule.seq ({
+ TokenType.SLASH_2,
+ Rule.one_of ({
+ TokenType.SLASH_2,
+ Rule.seq ({ optional_spaces, run, TokenType.SLASH_2 })
+ })
+ })
+ .set_name ("Italic")
+ .set_start (() => { push (_factory.create_run (Run.Style.ITALIC)); });
+
+ Rule underlined =
+ Rule.seq ({
+ TokenType.UNDERSCORE_2,
+ Rule.one_of ({
+ TokenType.UNDERSCORE_2,
+ Rule.seq ({ optional_spaces, run, TokenType.UNDERSCORE_2 })
+ })
+ })
+ .set_name ("Underlined")
+ .set_start (() => { push (_factory.create_run (Run.Style.UNDERLINED)); });
+
+ Rule monospace =
+ Rule.seq ({
+ TokenType.BACK_QUOTE_2,
+ Rule.one_of ({
+ TokenType.BACK_QUOTE_2,
+ Rule.seq ({ optional_spaces, run, TokenType.BACK_QUOTE_2 })
+ })
+ })
+ .set_name ("Monospace")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); });
+
+ Rule embedded =
+ Rule.seq ({
+ TokenType.DOUBLE_OPEN_BRACE.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (true); }),
+ TokenType.any_word ().action ((token) => { ((Embedded) peek ()).url = token.to_string (); }),
+ Rule.option ({
+ TokenType.PIPE.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (false); }),
+ text
+ })
+ .set_reduce (() => { var caption = pop () as Text; ((Embedded) peek ()).caption = caption.content; }),
+ TokenType.DOUBLE_CLOSED_BRACE.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (false); })
+ })
+ .set_name ("Embedded")
+ .set_start (() => { push (_factory.create_embedded ()); });
+
+ Rule link =
+ Rule.seq ({
+ TokenType.DOUBLE_OPEN_BRACKET.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (true); }),
+ TokenType.any_word ().action ((token) => {
+ var url = token.to_string ();
+ if (url.has_suffix (".valadoc")) {
+ var link = _factory.create_wiki_link ();
+ link.name = url;
+ push (link);
+ } else {
+ var link = _factory.create_link ();
+ link.url = url;
+ push (link);
+ }
+ }),
+ Rule.option ({
+ TokenType.PIPE.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (false); }),
+ run
+ }),
+ TokenType.DOUBLE_CLOSED_BRACKET.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (false); })
+ })
+ .set_name ("Link");
+ Rule source_code =
+ Rule.seq ({
+ TokenType.TRIPLE_OPEN_BRACE.action ((token) => { ((WikiScanner) _scanner).set_code_escape_mode (true); }),
+ TokenType.any_word ().action ((token) => { ((SourceCode) peek ()).code = token.to_string (); }),
+ TokenType.TRIPLE_CLOSED_BRACE.action ((token) => { ((WikiScanner) _scanner).set_code_escape_mode (false); })
+ })
+ .set_name ("SourceCode")
+ .set_start (() => { push (_factory.create_source_code ()); });
+
+ Rule.Action append_head_to_head2 = () => {
+ var head = (Inline) pop ();
+ ((InlineContent) peek ()).content.add (head);
+ };
+
+ Rule run_subrules =
+ Rule.one_of ({
+ Rule.seq ({
+ text
+ })
+ .set_reduce (append_head_to_head2),
+ Rule.seq ({
+ Rule.one_of ({
+ inline_taglet, bold, italic, underlined, monospace, embedded, link, source_code
+ })
+ .set_reduce (append_head_to_head2),
+ optional_spaces
+ })
+ });
+
+ Rule run_arobase =
+ Rule.seq ({
+ TokenType.AROBASE.action (add_text)
+ })
+ .set_reduce (append_head_to_head2);
+
+ run.set_rule (
+ Rule.seq ({
+ run_subrules,
+ optional_spaces,
+ Rule.option ({
+ Rule.many ({
+ Rule.one_of ({
+ run_arobase,
+ run_subrules,
+ optional_spaces
+ })
+ })
+ })
+ })
+ .set_name ("Run")
+ );
+
+
+ // Block rules
+
+ Rule paragraph =
+ Rule.seq ({
+ Rule.option ({
+ Rule.one_of ({
+ TokenType.ALIGN_CENTER.action (() => { ((Paragraph) peek ()).horizontal_align = HorizontalAlign.CENTER; }),
+ TokenType.ALIGN_RIGHT.action (() => { ((Paragraph) peek ()).horizontal_align = HorizontalAlign.RIGHT; })
+ })
+ }),
+ Rule.many ({
+ run,
+ TokenType.EOL.action (() => { add_content_space (); })
+ })
+ })
+ .set_name ("Paragraph")
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => {
+ var head = (Paragraph) pop ();
+ ((BlockContent) peek ()).content.add (head);
+
+ Text last_element = head.content.last () as Text;
+ if (last_element != null) {
+ last_element.content._chomp ();
+ }
+ });
+
+ Rule warning =
+ Rule.seq ({
+ TokenType.str ("Warning:"),
+ optional_invisible_spaces,
+ Rule.many ({
+ Rule.seq({optional_invisible_spaces, run}),
+ TokenType.EOL.action (() => { add_content_space (); })
+ })
+ })
+ .set_name ("Warning")
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => {
+ var head = _factory.create_warning ();
+ head.content.add ((Paragraph) pop ());
+ ((BlockContent) peek ()).content.add (head);
+
+ Text last_element = head.content.last () as Text;
+ if (last_element != null) {
+ last_element.content._chomp ();
+ }
+ });
+
+ Rule note =
+ Rule.seq ({
+ TokenType.str ("Note:"),
+ optional_invisible_spaces,
+ Rule.many ({
+ Rule.seq({optional_invisible_spaces, run}),
+ TokenType.EOL.action (() => { add_content_space (); })
+ })
+ })
+ .set_name ("Note")
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => {
+ var head = _factory.create_note ();
+ head.content.add ((Paragraph) pop ());
+ ((BlockContent) peek ()).content.add (head);
+
+ Text last_element = head.content.last () as Text;
+ if (last_element != null) {
+ last_element.content._chomp ();
+ }
+ });
+
+ Rule indented_item =
+ Rule.seq ({
+ Rule.many ({
+ TokenType.SPACE.action ((token) => { current_level++; })
+ }),
+ Rule.option ({
+ Rule.one_of ({
+ TokenType.str (".").action ((token) => { new_list_item (Content.List.Bullet.NONE); }),
+ TokenType.str ("*").action ((token) => { new_list_item (Content.List.Bullet.UNORDERED); }),
+ TokenType.str ("#").action ((token) => { new_list_item (Content.List.Bullet.ORDERED); }),
+ TokenType.str ("1.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_NUMBER); }),
+ TokenType.str ("a.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_LOWER_CASE_ALPHA); }),
+ TokenType.str ("A.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_UPPER_CASE_ALPHA); }),
+ TokenType.str ("i.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_LOWER_CASE_ROMAN); }),
+ TokenType.str ("I.").action ((token) => { new_list_item (Content.List.Bullet.ORDERED_UPPER_CASE_ROMAN); })
+ }),
+ optional_invisible_spaces
+ })
+ .set_skip (() => { new_list_item (Content.List.Bullet.NONE); }),
+ Rule.seq ({ run })
+ .set_start (() => {
+ var content = _factory.create_paragraph ();
+ ((ListItem) peek ()).content.add (content);
+ push (content);
+ })
+ .set_reduce (() => { pop (); }),
+ TokenType.EOL
+ })
+ .set_name ("IndentedItem")
+ .set_start (() => { current_level = 0; })
+ .set_reduce (() => {
+ var content_list = ((ListItem) peek ()).content;
+ if (content_list.size > 0 && content_list.last () is Text) {
+ ((Text) content_list.last ()).content._chomp ();
+ }
+ });
+
+ Rule indented_blocks =
+ Rule.many ({
+ indented_item
+ })
+ .set_name ("IndentedBlocks")
+ .set_reduce (() => { finish_list (); });
+
+ Rule table_cell_attributes =
+ Rule.seq ({
+ TokenType.LESS_THAN,
+ Rule.option ({
+ Rule.one_of ({
+ Rule.seq ({
+ Rule.option ({
+ Rule.one_of ({
+ TokenType.ALIGN_RIGHT.action ((token) => { ((TableCell) peek ()).horizontal_align = HorizontalAlign.RIGHT; }),
+ TokenType.ALIGN_CENTER.action ((token) => { ((TableCell) peek ()).horizontal_align = HorizontalAlign.CENTER; })
+ })
+ }),
+ Rule.option ({
+ Rule.one_of ({
+ TokenType.ALIGN_TOP.action ((token) => { ((TableCell) peek ()).vertical_align = VerticalAlign.TOP; }),
+ TokenType.ALIGN_BOTTOM.action ((token) => { ((TableCell) peek ()).vertical_align = VerticalAlign.BOTTOM; })
+ })
+ })
+ }),
+ TokenType.any_word ().action ((token) => { ((TableCell) peek ()).style = token.to_string (); })
+ })
+ }),
+ Rule.option ({
+ Rule.one_of ({
+ Rule.seq ({
+ TokenType.PIPE,
+ TokenType.any_number ().action ((token) => { ((TableCell) peek ()).rowspan = token.to_int (); })
+ }),
+ Rule.seq ({
+ TokenType.MINUS,
+ TokenType.any_number ().action ((token) => { ((TableCell) peek ()).colspan = token.to_int (); })
+ })
+ })
+ }),
+ TokenType.GREATER_THAN
+ })
+ .set_name ("CellAttributes");
+ Rule table_cell =
+ Rule.seq ({
+ Rule.seq ({
+ Rule.option ({
+ table_cell_attributes
+ }),
+ optional_invisible_spaces,
+ run
+ }),
+ TokenType.DOUBLE_PIPE
+ })
+ .set_name ("Cell")
+ .set_start (() => { push (_factory.create_table_cell ()); })
+ .set_reduce (() => {
+ var head = (TableCell) pop ();
+ ((TableRow) peek ()).cells.add (head);
+
+ if (head.content.size > 0 && head.content.last () is Text) {
+ ((Text) head.content.last ()).content._chomp ();
+ }
+ });
+ Rule table_row =
+ Rule.seq ({
+ TokenType.DOUBLE_PIPE,
+ Rule.many ({
+ table_cell
+ }),
+ TokenType.EOL
+ })
+ .set_name ("Row")
+ .set_start (() => { push (_factory.create_table_row ()); })
+ .set_reduce (() => {
+ var head = (TableRow) pop ();
+ ((Table) peek ()).rows.add (head);
+ });
+ Rule table =
+ Rule.seq ({
+ Rule.many ({
+ table_row
+ })
+ })
+ .set_name ("Table")
+ .set_start (() => { push (_factory.create_table ()); })
+ .set_reduce (() => {
+ var head = (Block) pop ();
+ ((BlockContent) peek ()).content.add (head);
+ });
+
+ Rule headline =
+ Rule.one_of ({
+ Rule.seq ({
+ TokenType.EQUAL_1.action ((token) => { ((Headline) peek ()).level = 1; }),
+ optional_invisible_spaces,
+ run,
+ optional_invisible_spaces,
+ TokenType.EQUAL_1,
+ TokenType.EOL
+ }),
+ Rule.seq ({
+ TokenType.EQUAL_2.action ((token) => { ((Headline) peek ()).level = 2; }),
+ optional_invisible_spaces,
+ run,
+ optional_invisible_spaces,
+ TokenType.EQUAL_2,
+ TokenType.EOL
+ }),
+ Rule.seq ({
+ TokenType.EQUAL_3.action ((token) => { ((Headline) peek ()).level = 3; }),
+ optional_invisible_spaces,
+ run,
+ optional_invisible_spaces,
+ TokenType.EQUAL_3,
+ TokenType.EOL
+ }),
+ Rule.seq ({
+ TokenType.EQUAL_4.action ((token) => { ((Headline) peek ()).level = 4; }),
+ optional_invisible_spaces,
+ run,
+ optional_invisible_spaces,
+ TokenType.EQUAL_4,
+ TokenType.EOL
+ }),
+ Rule.seq ({
+ TokenType.EQUAL_5.action ((token) => { ((Headline) peek ()).level = 5; }),
+ optional_invisible_spaces,
+ run,
+ optional_invisible_spaces,
+ TokenType.EQUAL_5,
+ TokenType.EOL
+ })
+ })
+ .set_name ("Headline")
+ .set_start (() => { push (_factory.create_headline ()); })
+ .set_reduce (() => {
+ var head = (Block) pop ();
+ ((BlockContent) peek ()).content.add (head);
+ });
+
+ Rule blocks =
+ Rule.one_of ({
+ indented_blocks,
+ table,
+ headline,
+ warning,
+ note,
+ paragraph
+ })
+ .set_name ("Blocks");
+
+ Rule page =
+ Rule.seq ({
+ blocks,
+ Rule.option ({
+ Rule.many ({
+ TokenType.EOL,
+ Rule.option ({ blocks })
+ })
+ })
+ })
+ .set_name ("Page")
+ .set_start (() => { push (_factory.create_page ()); });
+
+ Rule description =
+ Rule.seq ({
+ blocks,
+ Rule.option ({
+ Rule.many ({
+ TokenType.EOL,
+ Rule.option ({ blocks })
+ })
+ })
+ })
+ .set_name ("Description");
+
+ multiline_block_run =
+ Rule.seq ({
+ multiline_run
+ })
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => {
+ Paragraph p = (Paragraph) pop ();
+ ((BlockContent) peek ()).content.add (p);
+ })
+ .set_name ("BlockMultilineRun");
+
+ Rule taglet =
+ Rule.seq ({
+ TokenType.AROBASE,
+ TokenType.any_word ().action ((token) => {
+
+ string tag_name = token.to_string ();
+ var taglet = _factory.create_taglet (tag_name);
+ if (!(taglet is Block)) {
+ _parser.error (token, "Invalid taglet in this context");
+ }
+ push (taglet);
+
+ Rule? taglet_rule;
+ if (taglet is BlockContent) {
+ taglet_rule = taglet.get_parser_rule (multiline_block_run);
+ } else {
+ taglet_rule = taglet.get_parser_rule (multiline_run);
+ }
+
+ if (taglet_rule != null) {
+ _parser.push_rule (Rule.seq ({ TokenType.SPACE, taglet_rule }));
+ }
+ }),
+ Rule.option ({
+ Rule.many ({ TokenType.EOL })
+ })
+ })
+ .set_name ("Taglet")
+ .set_reduce (() => {
+ var head = (Taglet) pop ();
+ ((Comment) peek ()).taglets.add (head);
+ });
+
+ Rule comment =
+ Rule.seq ({
+ TokenType.EOL,
+ Rule.option ({
+ description
+ }),
+ Rule.option ({
+ Rule.many ({ taglet })
+ })
+ })
+ .set_name ("Comment")
+ .set_start (() => { push (_factory.create_comment ()); });
+
+ _comment_parser.set_root_rule (comment);
+ _wiki_parser.set_root_rule (page);
+ }
+
+ #if DEBUG
+ private void dump_stack (string title) {
+ message ("=== Dumping stack: %s ===", title);
+ foreach (Object object in _stack) {
+ message ("%s", object.get_type ().name ());
+ }
+ }
+ #endif
+ }
--- /dev/null
-using Gee;
-
+ /* girmetadata.vala
+ *
+ * Copyright (C) 2012-2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Brosch Florian <flo.brosch@gmail.com>
+ */
+
+
+ /**
+ * Metadata reader for GIR files
+ */
+ public class Valadoc.GirMetaData : Object {
+ private string? metadata_path = null;
+ private string? resource_dir = null;
+
+
+ public bool is_docbook { private set; get; default = false; }
+ public string index_sgml { private set; get; default = null; }
+ public string index_sgml_online { private set; get; default = null; }
+
+ /**
+ * Used to manipulate paths to resources inside gir-files
+ */
+ public string get_resource_path (string resource) {
+ if (resource_dir == null || metadata_path == null) {
+ return resource;
+ }
+
+ if (Path.is_absolute (resource_dir)) {
+ return Path.build_filename (resource_dir, resource);
+ }
+
+ return Path.build_filename (Path.get_dirname (metadata_path), resource_dir, resource);
+ }
+
+ private string? get_metadata_file_name (string gir_file_path) {
+ string metadata_file_name = Path.get_basename (gir_file_path);
+ int last_dot_pos = metadata_file_name.last_index_of (".");
+ if (last_dot_pos < 0) {
+ return null;
+ }
+
+ metadata_file_name = metadata_file_name.substring (0, last_dot_pos);
+ return metadata_file_name + ".valadoc.metadata";
+ }
+
+ private string? get_metadata_path (string gir_file_path, string[] metadata_dirs) {
+ string? metadata_file_name = get_metadata_file_name (gir_file_path);
+ if (metadata_file_name == null) {
+ return null;
+ }
+
+ // search for metatada at the same location as the gir file
+ string metadata_path = Path.build_filename (Path.get_dirname (gir_file_path), metadata_file_name);
+ if (FileUtils.test (metadata_path, FileTest.IS_REGULAR)) {
+ return metadata_path;
+ }
+
+ foreach (string metadata_dir in metadata_dirs) {
+ metadata_path = Path.build_filename (metadata_dir, metadata_file_name);
+ if (FileUtils.test (metadata_path, FileTest.IS_REGULAR)) {
+ return metadata_path;
+ }
+ }
+
+ return null;
+ }
+
+ private void load_general_metadata (KeyFile key_file, ErrorReporter reporter) throws KeyFileError {
+ foreach (string key in key_file.get_keys ("General")) {
+ switch (key) {
+ case "resources":
+ this.resource_dir = key_file.get_string ("General", "resources");
+ break;
+
+ case "is_docbook":
+ this.is_docbook = key_file.get_boolean ("General", "is_docbook");
+ break;
+
+ case "index_sgml":
+ string tmp = key_file.get_string ("General", "index_sgml");
+ this.index_sgml = Path.build_filename (Path.get_dirname (metadata_path), tmp);
+ break;
+
+ case "index_sgml_online":
+ this.index_sgml_online = key_file.get_string ("General", "index_sgml_online");
+ break;
+
+ default:
+ reporter.simple_warning (metadata_path, "Unknown key 'General.%s'", key);
+ break;
+ }
+ }
+ }
+
+ public GirMetaData (string gir_file_path, string[] metadata_dirs, ErrorReporter reporter) {
+ if (!FileUtils.test (gir_file_path, FileTest.IS_REGULAR)) {
+ return ;
+ }
+
+ metadata_path = get_metadata_path (gir_file_path, metadata_dirs);
+ if (metadata_path == null) {
+ return ;
+ }
+
+ KeyFile key_file;
+
+ try {
+ key_file = new KeyFile ();
+ key_file.load_from_file (metadata_path, KeyFileFlags.NONE);
+ } catch (KeyFileError e) {
+ reporter.simple_error (metadata_path, "%s", e.message);
+ return ;
+ } catch (FileError e) {
+ reporter.simple_error (metadata_path, "%s", e.message);
+ return ;
+ }
+
+ try {
+ foreach (string group in key_file.get_groups ()) {
+ switch (group) {
+ case "General":
+ load_general_metadata (key_file, reporter);
+ break;
+
+ default:
+ reporter.simple_warning (metadata_path, "Unknown group '%s'", group);
+ break;
+ }
+ }
+ } catch (KeyFileError e) {
+ reporter.simple_error (null, "Unable to read file '%s': %s", metadata_path, e.message);
+ }
+
+
+ // Load internal link lut:
+ }
+ }
+
--- /dev/null
-using Gee;
-
-
+ /* gtkcommentparser.vala
+ *
+ * Copyright (C) 2011-2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Content;
+ using Valadoc.Gtkdoc;
- private LinkedList<string> stack = new LinkedList<string> ();
- private LinkedList<LinkedList<Block>> footnotes = new LinkedList<LinkedList<Block>> ();
+
+ public class Valadoc.Gtkdoc.Parser : Object, ResourceLocator {
+ private Scanner scanner = new Scanner ();
+ private Token current;
+
- MapIterator<string, Api.SourceComment> iter = gir_comment.parameter_iterator ();
++ private Vala.List<string> stack = new Vala.ArrayList<string> (str_equal);
++ private Vala.List<Vala.List<Block>> footnotes = new Vala.ArrayList<Vala.ArrayList<Block>> ();
+
+ private ContentFactory factory;
+ private ErrorReporter reporter;
+ private Settings settings;
+ private Api.Tree tree;
+ private Api.Node? element;
+
+ private bool show_warnings;
+ private Api.SourceComment comment;
+ private unowned string instance_param_name;
+
+ private string[]? comment_lines;
+
+ private Regex? is_numeric_regex = null;
+ private Regex? normalize_regex = null;
+ private Regex regex_source_lang = null;
+
+ private Importer.InternalIdRegistrar id_registrar = null;
+ private GirMetaData? current_metadata = null;
+
+ private inline string fix_resource_path (string path) {
+ return this.current_metadata.get_resource_path (path);
+ }
+
+ private void reset (Api.SourceComment comment) {
+ this.scanner.reset (comment.content);
+ this.show_warnings = !comment.file.package.is_package;
+ this.comment_lines = null;
+ this.footnotes.clear ();
+ this.comment = comment;
+ this.current = null;
+ this.stack.clear ();
+ }
+
+ private string normalize (string text) {
+ try {
+ return normalize_regex.replace (text, -1, 0, " ");
+ } catch (RegexError e) {
+ assert_not_reached ();
+ }
+ }
+
+ private bool is_numeric (string str) {
+ return is_numeric_regex.match (str);
+ }
+
+ private void report_unexpected_token (Token got, string expected) {
+ report_warning (got, "Unexpected Token: %s (Expected: %s)".printf (got.to_string (), expected));
+ }
+
+ private void report_warning (Token got, string message) {
+ if (!this.show_warnings) {
+ return ;
+ }
+
+ int startpos = (got.line == 0)? comment.first_column + got.first_column : got.first_column;
+ int endpos = (got.line == 0)? comment.first_column + got.last_column : got.last_column;
+
+ if (this.comment_lines == null) {
+ this.comment_lines = this.comment.content.split ("\n");
+ }
+
+ this.reporter.warning (this.comment.file.get_name (),
+ comment.first_line + got.line,
+ startpos + 1,
+ endpos + 1,
+ this.comment_lines[got.line],
+ message);
+ }
+
+ public Parser (Settings settings, ErrorReporter reporter, Api.Tree tree, ModuleLoader modules) {
+ this.factory = new ContentFactory (settings, this, modules);
+ this.reporter = reporter;
+ this.settings = settings;
+ this.tree = tree;
+
+ try {
+ is_numeric_regex = new Regex ("^[+-]?([0-9]*\\.?[0-9]+|[0-9]+\\.?[0-9]*)([eE][+-]?[0-9]+)?$",
+ RegexCompileFlags.OPTIMIZE);
+ normalize_regex = new Regex ("( |\n|\t)+", RegexCompileFlags.OPTIMIZE);
+ regex_source_lang = new Regex ("^<!--[ \t]+language=\"([A-Za-z]*)\"[ \t]+-->");
+ } catch (RegexError e) {
+ assert_not_reached ();
+ }
+ }
+
+ private Note? _parse_note (Api.SourceComment comment) {
+ Comment? cmnt = parse_root_content (comment);
+ if (cmnt == null) {
+ return null;
+ }
+
+ Note note = factory.create_note ();
+ note.content.add_all (cmnt.content);
+
+ return note;
+ }
+
+ private void add_note (ref Comment? comment, Note? note) {
+ if (note == null) {
+ return ;
+ }
+
+ if (comment == null) {
+ comment = factory.create_comment ();
+ }
+
+ if (comment.content.size == 0) {
+ comment.content.add (factory.create_paragraph ());
+ }
+
+ comment.content.insert (1, note);
+ }
+
+ private void add_taglet (ref Comment? comment, Taglet? taglet) {
+ if (taglet == null) {
+ return ;
+ }
+
+ if (comment == null) {
+ comment = factory.create_comment ();
+ }
+
+ comment.taglets.add (taglet);
+ }
+
+ public Comment? parse (Api.Node element, Api.GirSourceComment gir_comment, GirMetaData gir_metadata, Importer.InternalIdRegistrar id_registrar) {
+ this.instance_param_name = gir_comment.instance_param_name;
+ this.current_metadata = gir_metadata;
+ this.id_registrar = id_registrar;
+ this.element = element;
+
+
+ Comment? cmnt = parse_root_content (gir_comment);
+ if (cmnt != null) {
+ ImporterHelper.extract_short_desc (cmnt, factory);
+ }
+
+
+ // deprecated:
+ if (gir_comment.deprecated_comment != null) {
+ Note? note = _parse_note (gir_comment.deprecated_comment);
+ add_note (ref cmnt, note);
+ }
+
+
+ // version:
+ if (gir_comment.version_comment != null) {
+ Note? note = _parse_note (gir_comment.version_comment);
+ add_note (ref cmnt, note);
+ }
+
+ // stability:
+ if (gir_comment.stability_comment != null) {
+ Note? note = _parse_note (gir_comment.stability_comment);
+ add_note (ref cmnt, note);
+ }
+
+
+ // return:
+ if (gir_comment.return_comment != null) {
+ Taglet? taglet = parse_block_taglet (gir_comment.return_comment, "return");
+ add_taglet (ref cmnt, taglet);
+ }
+
+
+ // parameters:
- foreach (LinkedList<Block> note in this.footnotes) {
++ Vala.MapIterator<string, Api.SourceComment> iter = gir_comment.parameter_iterator ();
+ for (bool has_next = iter.next (); has_next; has_next = iter.next ()) {
+ Taglets.Param? taglet = parse_block_taglet (iter.get_value (), "param") as Taglets.Param;
+ string param_name = iter.get_key ();
+
+ taglet.is_c_self_param = (param_name == gir_comment.instance_param_name);
+ taglet.parameter_name = param_name;
+ add_taglet (ref cmnt, taglet);
+ }
+
+
+ bool first = true;
- stack.offer_head (tagname);
++ foreach (Vala.List<Block> note in this.footnotes) {
+ if (first == true && note.size > 0) {
+ Paragraph p = note.first () as Paragraph;
+ if (p == null) {
+ p = factory.create_paragraph ();
+ cmnt.content.add (p);
+ }
+
+ p.content.insert (0, factory.create_text ("\n"));
+ }
+ cmnt.content.add_all (note);
+ first = false;
+ }
+
+ return cmnt;
+ }
+
+ private Taglet? parse_block_taglet (Api.SourceComment gir_comment, string taglet_name) {
+ this.reset (gir_comment);
+ current = null;
+ next ();
+
+ parse_docbook_spaces (false);
+ var ic = parse_inline_content ();
+ parse_docbook_spaces (false);
+
+ if (current.type != TokenType.EOF) {
+ this.report_unexpected_token (current, "<EOF>");
+ return null;
+ }
+
+ BlockContent? taglet = factory.create_taglet (taglet_name) as BlockContent;
+ assert (taglet != null);
+ Paragraph paragraph = factory.create_paragraph ();
+ paragraph.content.add (ic);
+ taglet.content.add (paragraph);
+ return taglet as Taglet;
+ }
+
+ private Comment? parse_root_content (Api.SourceComment gir_comment) {
+ this.reset (gir_comment);
+ current = null;
+
+ next ();
+
+ Token tmp = null;
+ parse_docbook_spaces (false);
+
+ Comment comment = factory.create_comment ();
+ while (current.type != TokenType.EOF && tmp != current) {
+ tmp = current;
+ var ic = parse_inline_content ();
+ if (ic != null && ic.content.size > 0) {
+ Paragraph p = factory.create_paragraph ();
+ p.content.add (ic);
+ comment.content.add (p);
+ }
+
+ var bc = parse_block_content ();
+ if (bc != null && bc.size > 0) {
+ comment.content.add_all (bc);
+ }
+ }
+
+ if (current.type != TokenType.EOF) {
+ this.report_unexpected_token (current, "<INLINE|BLOCK>");
+ return null;
+ }
+
+ ImporterHelper.extract_short_desc (comment, factory);
+
+ return comment;
+ }
+
+
+
+ //
+ // Common:
+ //
+
+ private Token next () {
+ current = scanner.next ();
+ return current;
+ }
+
+ private bool ignore_current_xml_close () {
+ if (current.type != TokenType.XML_CLOSE) {
+ return false;
+ }
+
+ string name = current.content;
+ if ((name in stack) == false) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool check_xml_open_tag (string tagname) {
+ if ((current.type == TokenType.XML_OPEN && current.content != tagname)
+ || current.type != TokenType.XML_OPEN)
+ {
+ return false;
+ }
+
- if (stack.poll_head () == tagname) {
- stack.peek_head ();
- }
++ stack.insert (0, tagname);
+ return true;
+ }
+
+ private bool check_xml_close_tag (string tagname) {
+ if ((current.type == TokenType.XML_CLOSE && current.content != tagname)
+ || current.type != TokenType.XML_CLOSE)
+ {
+ return false;
+ }
+
- private inline LinkedList<Block>? parse_docbook_orderedlist () {
++ assert (stack.remove_at (0) == tagname);
+
+ return true;
+ }
+
+
+ private void parse_docbook_spaces (bool accept_paragraphs = true) {
+ while (true) {
+ if (current.type == TokenType.SPACE) {
+ next ();
+ } else if (current.type == TokenType.NEWLINE) {
+ next ();
+ } else if (accept_paragraphs && current.type == TokenType.GTKDOC_PARAGRAPH) {
+ next ();
+ } else {
+ break;
+ }
+ }
+ }
+
+
+
+ //
+ // Rules, Ground:
+ //
+
+ private Inline? parse_docbook_link_tempalte (string tagname, bool is_internal) {
+ if (!check_xml_open_tag (tagname)) {
+ this.report_unexpected_token (current, "<%s>".printf (tagname));
+ return null;
+ }
+
+ StringBuilder builder = new StringBuilder ();
+ string url = current.attributes.get ("linkend");
+ next ();
+
+ // TODO: check xml
+ while (!(current.type == TokenType.XML_CLOSE && current.content == tagname)
+ && current.type != TokenType.EOF)
+ {
+ if (current.type == TokenType.XML_OPEN) {
+ } else if (current.type == TokenType.XML_CLOSE) {
+ } else if (current.type == TokenType.XML_COMMENT) {
+ } else {
+ builder.append (current.content);
+ }
+
+ next ();
+ }
+
+ var link = factory.create_link ();
+ if (is_internal) {
+ link.id_registrar = id_registrar;
+ }
+ link.url = url;
+
+ if (builder.len == 0) {
+ link.content.add (factory.create_text (url));
+ } else {
+ link.content.add (factory.create_text (normalize (builder.str)));
+ }
+
+ if (!check_xml_close_tag (tagname)) {
+ this.report_unexpected_token (current, "</%s>".printf (tagname));
+ return link;
+ }
+
+ next ();
+ return link;
+ }
+
+ private InlineTaglet? parse_symbol_link (string tagname) {
+ if (!check_xml_open_tag (tagname)) {
+ this.report_unexpected_token (current, "<%s>".printf (tagname));
+ return null;
+ }
+
+ if (next ().type == TokenType.SPACE) {
+ next ();
+ }
+
+ InlineTaglet? taglet = null;
+
+ if (current.type == TokenType.WORD && current.content == "struct") {
+ next ();
+
+ if (next ().type == TokenType.SPACE) {
+ next ();
+ }
+ }
+
+
+ if (current.type == TokenType.GTKDOC_FUNCTION || current.type == TokenType.GTKDOC_CONST
+ || current.type == TokenType.GTKDOC_TYPE || current.type == TokenType.WORD
+ || current.type == TokenType.GTKDOC_PROPERTY || current.type == TokenType.GTKDOC_SIGNAL)
+ {
+ taglet = this.create_type_link (current.content) as InlineTaglet;
+ assert (taglet != null);
+ }
+
+ if (next ().type == TokenType.SPACE) {
+ next ();
+ }
+
+ if (!check_xml_close_tag (tagname)) {
+ this.report_unexpected_token (current, "</%s>".printf (tagname));
+ return taglet;
+ }
+
+ next ();
+ return taglet;
+ }
+
+ private void parse_anchor () {
+ if (!check_xml_open_tag ("anchor")) {
+ this.report_unexpected_token (current, "<anchor>");
+ return;
+ }
+
+ string id = current.attributes.get ("id");
+ if (id != null) {
+ id_registrar.register_symbol (id, element);
+ }
+ next ();
+
+ if (!check_xml_close_tag ("anchor")) {
+ this.report_unexpected_token (current, "</anchor>");
+ return;
+ }
+
+ next ();
+ }
+
+ private Link? parse_xref () {
+ if (!check_xml_open_tag ("xref")) {
+ this.report_unexpected_token (current, "<xref>");
+ return null;
+ }
+
+ string linkend = current.attributes.get ("linkend");
+ next ();
+
+ Link link = factory.create_link ();
+ link.content.add (factory.create_text (linkend));
+ link.id_registrar = id_registrar;
+ link.url = linkend;
+
+ if (!check_xml_close_tag ("xref")) {
+ this.report_unexpected_token (current, "</xref>");
+ return link;
+ }
+
+ next ();
+ return link;
+ }
+
+ private Run? parse_highlighted_template (string tag_name, Run.Style style) {
+ if (!check_xml_open_tag (tag_name)) {
+ this.report_unexpected_token (current, "<%s>".printf (tag_name));
+ return null;
+ }
+
+ next ();
+ Run run = parse_inline_content ();
+ if (run.style != Run.Style.NONE && run.style != style) {
+ Run tmp = factory.create_run (style);
+ tmp.content.add (run);
+ run = tmp;
+ } else {
+ run.style = style;
+ }
+
+ if (!check_xml_close_tag (tag_name)) {
+ this.report_unexpected_token (current, "</%s>".printf (tag_name));
+ return run;
+ }
+
+ next ();
+ return run;
+ }
+
+ private ListItem? parse_docbook_listitem () {
+ if (!check_xml_open_tag ("listitem")) {
+ this.report_unexpected_token (current, "<listitem>");
+ return null;
+ }
+
+ next ();
+
+ ListItem item = factory.create_list_item ();
+
+ item.content.add_all (parse_mixed_content ());
+
+ if (!check_xml_close_tag ("listitem")) {
+ this.report_unexpected_token (current, "</listitem>");
+ return item;
+ }
+
+ next ();
+ return item;
+ }
+
+ private BlockContent? parse_docbook_information_box_template (string tagname, BlockContent container) {
+ if (!check_xml_open_tag (tagname)) {
+ this.report_unexpected_token (current, "<%s>".printf (tagname));
+ return null;
+ }
+
+ next ();
+ parse_docbook_spaces ();
+
+ Token tmp = null;
+ while (current.type != TokenType.XML_CLOSE && current.type != TokenType.EOF) {
+ tmp = current;
+ var ic = parse_inline_content ();
+ if (ic != null && ic.content.size > 0) {
+ Paragraph p = factory.create_paragraph ();
+ p.content.add (ic);
+ container.content.add (p);
+ }
+
+ var bc = parse_block_content ();
+ if (bc != null && bc.size > 0) {
+ container.content.add_all (bc);
+ }
+ }
+
+ parse_docbook_spaces ();
+
+ if (!check_xml_close_tag (tagname)) {
+ this.report_unexpected_token (current, "</%s>".printf (tagname));
+ return container;
+ }
+
+ next ();
+ return container;
+ }
+
+ private Note? parse_docbook_important () {
+ return (Note?) parse_docbook_information_box_template ("important", factory.create_note ());
+ }
+
+ private Note? parse_docbook_note () {
+ return (Note?) parse_docbook_information_box_template ("note", factory.create_note ());
+ }
+
+ private Warning? parse_docbook_warning () {
+ return (Warning?) parse_docbook_information_box_template ("warning", factory.create_warning ());
+ }
+
- private LinkedList<Block>? parse_docbook_itemizedlist (string tag_name = "itemizedlist",
++ private inline Vala.Collection<Block>? parse_docbook_orderedlist () {
+ return parse_docbook_itemizedlist ("orderedlist", Content.List.Bullet.ORDERED);
+ }
+
- LinkedList<Block> content = new LinkedList<Block> ();
++ private Vala.Collection<Block>? parse_docbook_itemizedlist (string tag_name = "itemizedlist",
+ Content.List.Bullet bullet_type = Content.List.Bullet.UNORDERED)
+ {
+ if (!check_xml_open_tag (tag_name)) {
+ this.report_unexpected_token (current, "<%s>".printf (tag_name));
+ return null;
+ }
+ next ();
+
+
- private LinkedList<Block> parse_mixed_content () {
- LinkedList<Block> content = new LinkedList<Block> ();
++ Vala.Collection<Block> content = new Vala.ArrayList<Block> ();
+ parse_docbook_spaces ();
+
+ if (current.type == TokenType.XML_OPEN && current.content == "title") {
+ append_block_content_not_null (content, parse_docbook_title ());
+ parse_docbook_spaces ();
+ }
+
+ Content.List list = factory.create_list ();
+ list.bullet = bullet_type;
+ content.add (list);
+
+ while (current.type == TokenType.XML_OPEN) {
+ if (current.content == "listitem") {
+ list.items.add (parse_docbook_listitem ());
+ } else {
+ break;
+ }
+
+ parse_docbook_spaces ();
+ }
+
+ if (!check_xml_close_tag (tag_name)) {
+ this.report_unexpected_token (current, "</%s>".printf (tag_name));
+ return content;
+ }
+
+ next ();
+ return content;
+ }
+
+ private Paragraph? parse_gtkdoc_paragraph () {
+ if (current.type != TokenType.GTKDOC_PARAGRAPH) {
+ this.report_unexpected_token (current, "<GTKDOC-PARAGRAPH>");
+ return null;
+ }
+
+ next ();
+
+ Paragraph p = factory.create_paragraph ();
+
+ Run? run = parse_inline_content ();
+ p.content.add (run);
+ return p;
+ }
+
- LinkedList<Block> lst = parse_block_content ();
++ private Vala.Collection<Block> parse_mixed_content () {
++ Vala.Collection<Block> content = new Vala.ArrayList<Block> ();
+ Token tmp = null;
+
+ while (tmp != current) {
+ tmp = current;
+ parse_docbook_spaces ();
+
+ Run? run = parse_inline_content ();
+ if (run != null && run.content.size > 0) {
+ Paragraph p = factory.create_paragraph ();
+ p.content.add (run);
+ content.add (p);
+ continue;
+ }
+
- private inline LinkedList<Block>? parse_docbook_simpara () {
++ Vala.Collection<Block> lst = parse_block_content ();
+ if (lst != null && lst.size > 0) {
+ content.add_all (lst);
+ continue;
+ }
+ }
+
+ return content;
+ }
+
- private LinkedList<Block>? parse_docbook_para (string tag_name = "para") {
++ private inline Vala.Collection<Block>? parse_docbook_simpara () {
+ return parse_docbook_para ("simpara");
+ }
+
- LinkedList<Block> content = parse_mixed_content ();
++ private Vala.Collection<Block>? parse_docbook_para (string tag_name = "para") {
+ if (!check_xml_open_tag (tag_name)) {
+ this.report_unexpected_token (current, "<%s>".printf (tag_name));
+ return null;
+ }
+
+ next ();
+
- private LinkedList<Block>? parse_docbook_informalexample () {
++ Vala.Collection<Block> content = parse_mixed_content ();
+
+ // ignore missing </para> to match gtkdocs behaviour
+ if (!check_xml_close_tag (tag_name) && current.type != TokenType.EOF) {
+ this.report_unexpected_token (current, "</%s>".printf (tag_name));
+ return content;
+ }
+
+ next ();
+ return content;
+ }
+
+ private Paragraph? parse_gtkdoc_source () {
+ if (current.type != TokenType.GTKDOC_SOURCE_OPEN) {
+ this.report_unexpected_token (current, "|[");
+ return null;
+ }
+
+ StringBuilder builder = new StringBuilder ();
+ Token source_token = current;
+
+ for (next (); current.type != TokenType.EOF && current.type != TokenType.GTKDOC_SOURCE_CLOSE; next ()) {
+ if (current.type == TokenType.WORD) {
+ builder.append (current.content);
+ } else if (current.type != TokenType.XML_COMMENT) {
+ builder.append_len (current.start, current.length);
+ }
+ }
+
+ SourceCode code = factory.create_source_code ();
+ MatchInfo info;
+
+ unowned string source = builder.str;
+ if (regex_source_lang.match (source, 0, out info)) {
+ string lang_name = info.fetch (1).down ();
+ SourceCode.Language? lang = SourceCode.Language.from_string (lang_name);
+ code.language = lang;
+
+ if (lang == null) {
+ report_warning (source_token, "Unknown language `%s' in source code block |[<!-- language=\"\"".printf (lang_name));
+ }
+
+ source = source.offset (source.index_of_char ('>') + 1);
+ } else {
+ code.language = (Highlighter.XmlScanner.is_xml (source))
+ ? SourceCode.Language.XML
+ : SourceCode.Language.C;
+ }
+ code.code = source;
+
+ Paragraph p = factory.create_paragraph ();
+ p.content.add (code);
+
+ if (current.type != TokenType.GTKDOC_SOURCE_CLOSE) {
+ this.report_unexpected_token (current, "|]");
+ return p;
+ }
+
+ next ();
+ return p;
+ }
+
+ private Paragraph? parse_docbook_title () {
+ if (!check_xml_open_tag ("title")) {
+ this.report_unexpected_token (current, "<title>");
+ return null;
+ }
+
+ next ();
+
+ Paragraph p = factory.create_paragraph ();
+ Run content = parse_inline_content ();
+ content.content.add (factory.create_text (":"));
+ content.style = Run.Style.BOLD;
+ p.content.add (content);
+
+ if (!check_xml_close_tag ("title")) {
+ this.report_unexpected_token (current, "</title>");
+ return p;
+ }
+
+ next ();
+ return p;
+ }
+
+ private Paragraph? parse_docbook_graphic () {
+ var tmp = parse_docbook_inlinegraphic ("graphic");
+ if (tmp == null) {
+ return null;
+ }
+
+ Paragraph? p = factory.create_paragraph ();
+ p.content.add (tmp);
+ return p;
+ }
+
+ private Embedded? parse_docbook_inlinegraphic (string tag_name = "inlinegraphic") {
+ if (!check_xml_open_tag (tag_name)) {
+ this.report_unexpected_token (current, "<%s>".printf (tag_name));
+ return null;
+ }
+
+ Embedded e = factory.create_embedded ();
+ e.url = fix_resource_path (current.attributes.get ("fileref"));
+
+ next ();
+ parse_docbook_spaces ();
+
+ if (!check_xml_close_tag (tag_name)) {
+ this.report_unexpected_token (current, "</%s>".printf (tag_name));
+ return e;
+ }
+
+ next ();
+ return e;
+ }
+
+ private Paragraph? parse_docbook_programlisting () {
+ if (!check_xml_open_tag ("programlisting")) {
+ this.report_unexpected_token (current, "<programlisting>");
+ return null;
+ }
+
+ StringBuilder builder = new StringBuilder ();
+
+ for (next (); current.type != TokenType.EOF && !(current.type == TokenType.XML_CLOSE
+ && current.content == "programlisting"); next ())
+ {
+ if (current.type == TokenType.WORD) {
+ builder.append (current.content);
+ } else if (current.type != TokenType.XML_COMMENT) {
+ builder.append_len (current.start, current.length);
+ }
+ }
+
+ SourceCode src = factory.create_source_code ();
+ src.language = SourceCode.Language.C;
+ src.code = builder.str;
+
+ Paragraph p = factory.create_paragraph ();
+ p.content.add (src);
+
+ if (!check_xml_close_tag ("programlisting")) {
+ this.report_unexpected_token (current, "</programlisting>");
+ return p;
+ }
+
+ next ();
+ return p;
+ }
+
+ /*
- LinkedList<Block> content = new LinkedList<Block> ();
++ private Vala.Collection<Block>? parse_docbook_informalexample () {
+ if (!check_xml_open_tag ("informalexample")) {
+ this.report_unexpected_token (current, "<informalexample>");
+ return null;
+ }
+
+ next ();
+
+ parse_docbook_spaces ();
+
- private inline LinkedList<Block>? parse_docbook_informalexample () {
++ Vala.Collection<Block> content = new Vala.ArrayList<Block> ();
+
+ if (current.type == TokenType.XML_OPEN && current.content == "title") {
+ append_block_content_not_null (content, parse_docbook_title ());
+ parse_docbook_spaces ();
+ }
+
+ if (current.type == TokenType.XML_OPEN && current.content == "programlisting") {
+ append_block_content_not_null (content, parse_docbook_programlisting ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "inlinegraphic") {
+ Embedded? img = parse_docbook_inlinegraphic ();
+ Paragraph p = factory.create_paragraph ();
+ append_block_content_not_null (content, p);
+ p.content.add (img);
+
+ }
+
+ parse_docbook_spaces ();
+
+ if (!check_xml_close_tag ("informalexample")) {
+ this.report_unexpected_token (current, "</informalexample>");
+ return content;
+ }
+
+ next ();
+ return content;
+ }
+ */
+
- private LinkedList<Block>? parse_docbook_example (string tag_name = "example") {
++ private inline Vala.Collection<Block>? parse_docbook_informalexample () {
+ return parse_docbook_example ("informalexample");
+ }
+
- LinkedList<Block> content = new LinkedList<Block> ();
++ private Vala.Collection<Block>? parse_docbook_example (string tag_name = "example") {
+ if (!check_xml_open_tag (tag_name)) {
+ this.report_unexpected_token (current, "<%s>".printf (tag_name));
+ return null;
+ }
+
+ next ();
+
+ parse_docbook_spaces ();
+
- private LinkedList<Block>? parse_docbook_refsect2 (int nr = 2) {
++ Vala.Collection<Block> content = new Vala.ArrayList<Block> ();
+
+ content.add_all (parse_mixed_content ());
+
+ /*
+ while (current.type == TokenType.XML_OPEN) {
+ if (current.type == TokenType.XML_OPEN && current.content == "inlinegraphic") {
+ Paragraph p = factory.create_paragraph ();
+ while (current.type == TokenType.XML_OPEN && current.content == "inlinegraphic") {
+ p.content.add (parse_docbook_inlinegraphic ());
+ parse_docbook_spaces ();
+ }
+ } else if (current.type == TokenType.XML_OPEN && current.content == "programlisting") {
+ append_block_content_not_null (content, parse_docbook_programlisting ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "para") {
+ this.append_block_content_not_null_all (content, parse_docbook_para ());
+ } else {
+ break;
+ }
+
+ parse_docbook_spaces ();
+ } */
+
+ if (!check_xml_close_tag (tag_name)) {
+ this.report_unexpected_token (current, "</%s>".printf (tag_name));
+ return content;
+ }
+
+ next ();
+ return content;
+ }
+
- LinkedList<Block> content = new LinkedList<Block> ();
++ private Vala.List<Block>? parse_docbook_refsect2 (int nr = 2) {
+ if (!check_xml_open_tag ("refsect%d".printf (nr))) {
+ this.report_unexpected_token (current, "<refsect%d>".printf (nr));
+ return null;
+ }
+
+ string id = current.attributes.get ("id");
+ if (id != null) {
+ id_registrar.register_symbol (id, element);
+ }
+ next ();
+
+ parse_docbook_spaces ();
+
- private LinkedList<Block>? parse_docbook_figure () {
++ Vala.List<Block> content = new Vala.ArrayList<Block> ();
+
+ this.append_block_content_not_null_all (content, parse_mixed_content ());
+
+ if (!check_xml_close_tag ("refsect%d".printf (nr))) {
+ this.report_unexpected_token (current, "</refsect%d>".printf (nr));
+ return content;
+ }
+
+ next ();
+ return content;
+ }
+
- LinkedList<Block> content = new LinkedList<Block> ();
++ private Vala.List<Block>? parse_docbook_figure () {
+ if (!check_xml_open_tag ("figure")) {
+ this.report_unexpected_token (current, "<figure>");
+ return null;
+ }
+ next ();
+
- LinkedList<Block> content = new LinkedList<Block> ();
++ Vala.List<Block> content = new Vala.ArrayList<Block> ();
+ parse_docbook_spaces ();
+
+ if (current.type == TokenType.XML_OPEN && current.content == "title") {
+ append_block_content_not_null (content, parse_docbook_title ());
+ parse_docbook_spaces ();
+ }
+
+ while (current.type == TokenType.XML_OPEN) {
+ if (current.content == "inlinegraphic") {
+ Paragraph p = (content.size > 0)? content[0] as Paragraph : null;
+ if (p == null) {
+ p = factory.create_paragraph ();
+ }
+
+ while (current.type == TokenType.XML_OPEN && current.content == "inlinegraphic") {
+ p.content.add (parse_docbook_inlinegraphic ());
+ parse_docbook_spaces ();
+ }
+ } else if (current.content == "graphic") {
+ append_block_content_not_null (content, parse_docbook_graphic ());
+ } else {
+ break;
+ }
+
+ parse_docbook_spaces ();
+ }
+
+ if (!check_xml_close_tag ("figure")) {
+ this.report_unexpected_token (current, "</figure>");
+ return content;
+ }
+
+ next ();
+ return content;
+ }
+
+ private Run? parse_docbook_footnote () {
+ if (!check_xml_open_tag ("footnote")) {
+ this.report_unexpected_token (current, "<footnote>");
+ return null;
+ }
+ next ();
+
+ int counter = this.footnotes.size + 1;
+ Run? nr = factory.create_run (Run.Style.ITALIC);
+ nr.content.add (factory.create_text ("[%d] ".printf (counter)));
- private inline void append_block_content_not_null_all (LinkedList<Block> run, LinkedList<Block>? elements) {
++ Vala.List<Block> content = new Vala.ArrayList<Block> ();
+ this.footnotes.add (content);
+
+ content.add_all (parse_mixed_content ());
+
+ Paragraph? first = (content.is_empty)? null : content.first () as Paragraph;
+ if (first == null) {
+ first = factory.create_paragraph ();
+ content.insert (0, first);
+ }
+
+ Run entry = factory.create_run (Run.Style.ITALIC);
+ entry.content.add (factory.create_text (counter.to_string () + ": "));
+ first.content.insert (0, entry);
+
+ if (!check_xml_close_tag ("footnote")) {
+ this.report_unexpected_token (current, "</footnote>");
+ return nr;
+ }
+
+ next ();
+ return nr;
+ }
+
- private inline void append_block_content_not_null (LinkedList<Block> run, Block? element) {
++ private inline void append_block_content_not_null_all (Vala.Collection<Block> run, Vala.Collection<Block>? elements) {
+ if (elements != null) {
+ run.add_all (elements);
+ }
+ }
+
- private LinkedList<TableRow>? parse_docbook_tbody () {
++ private inline void append_block_content_not_null (Vala.Collection<Block> run, Block? element) {
+ if (element != null) {
+ run.add (element);
+ }
+ }
+
+ private TableRow? parse_docbook_thead () {
+ if (!check_xml_open_tag ("thead")) {
+ this.report_unexpected_token (current, "<thead>");
+ return null;
+ }
+ next ();
+
+ parse_docbook_spaces ();
+ TableRow? row = parse_docbook_row (Run.Style.BOLD);
+ parse_docbook_spaces ();
+
+ if (!check_xml_close_tag ("thead")) {
+ this.report_unexpected_token (current, "</thead>");
+ return row;
+ }
+
+ next ();
+ return row;
+ }
+
+ private TableCell? parse_docbook_entry (Run.Style default_style = Run.Style.NONE) {
+ if (!check_xml_open_tag ("entry")) {
+ this.report_unexpected_token (current, "<entry>");
+ return null;
+ }
+ next ();
+
+ TableCell cell = factory.create_table_cell ();
+ Run run = factory.create_run (default_style);
+ run.content.add (parse_inline_content ());
+ cell.content.add (run);
+
+ if (!check_xml_close_tag ("entry")) {
+ this.report_unexpected_token (current, "</entry>");
+ return cell;
+ }
+
+ next ();
+ return cell;
+ }
+
+ private TableRow? parse_docbook_row (Run.Style default_style = Run.Style.NONE) {
+ if (!check_xml_open_tag ("row")) {
+ this.report_unexpected_token (current, "<row>");
+ return null;
+ }
+ next ();
+
+ TableRow row = factory.create_table_row ();
+ parse_docbook_spaces ();
+
+ while (current.type == TokenType.XML_OPEN && current.content == "entry") {
+ TableCell? table_cell = parse_docbook_entry (default_style);
+ if (table_cell == null) {
+ break;
+ }
+
+ row.cells.add (table_cell);
+ parse_docbook_spaces ();
+ }
+
+ if (!check_xml_close_tag ("row")) {
+ this.report_unexpected_token (current, "</row>");
+ return row;
+ }
+
+ next ();
+ return row;
+ }
+
- LinkedList<TableRow> rows = new LinkedList<TableRow> ();
++ private Vala.Collection<TableRow>? parse_docbook_tbody () {
+ if (!check_xml_open_tag ("tbody")) {
+ this.report_unexpected_token (current, "<tbody>");
+ return null;
+ }
+ next ();
+
+ parse_docbook_spaces ();
+
- LinkedList<TableRow>? rows = parse_docbook_tbody ();
++ Vala.Collection<TableRow> rows = new Vala.ArrayList<TableRow> ();
+ while (current.type == TokenType.XML_OPEN && current.content == "row") {
+ TableRow? row = parse_docbook_row ();
+ if (row == null) {
+ break;
+ }
+
+ parse_docbook_spaces ();
+ rows.add (row);
+ }
+
+
+ if (!check_xml_close_tag ("tbody")) {
+ this.report_unexpected_token (current, "</tbody>");
+ return rows;
+ }
+
+ next ();
+ return rows;
+ }
+
+ private Table? parse_docbook_tgroup () {
+ if (!check_xml_open_tag ("tgroup")) {
+ this.report_unexpected_token (current, "<tgroup>");
+ return null;
+ }
+ next ();
+
+ Table table = factory.create_table ();
+ parse_docbook_spaces ();
+
+ if (current.type == TokenType.XML_OPEN && current.content == "thead") {
+ TableRow? row = parse_docbook_thead ();
+ if (row != null) {
+ parse_docbook_spaces ();
+ table.rows.add (row);
+ }
+
+ parse_docbook_spaces ();
+ }
+
+ if (current.type == TokenType.XML_OPEN && current.content == "tbody") {
- private LinkedList<Block>? parse_docbook_section () {
++ Vala.Collection<TableRow>? rows = parse_docbook_tbody ();
+ if (rows != null) {
+ table.rows.add_all (rows);
+ }
+
+ parse_docbook_spaces ();
+ }
+
+ if (!check_xml_close_tag ("tgroup")) {
+ this.report_unexpected_token (current, "</tgroup>");
+ return table;
+ }
+
+ next ();
+ return table;
+ }
+
+ private Table? parse_docbook_informaltable () {
+ if (!check_xml_open_tag ("informaltable")) {
+ this.report_unexpected_token (current, "<informaltable>");
+ return null;
+ }
+ next ();
+
+ parse_docbook_spaces ();
+ Table? table = this.parse_docbook_tgroup ();
+ parse_docbook_spaces ();
+
+ if (!check_xml_close_tag ("informaltable")) {
+ this.report_unexpected_token (current, "</informaltable>");
+ return table;
+ }
+
+ next ();
+ return table;
+ }
+
- LinkedList<Block> content = parse_mixed_content ();
++ private Vala.Collection<Block>? parse_docbook_section () {
+ if (!check_xml_open_tag ("section")) {
+ this.report_unexpected_token (current, "<section>");
+ return null;
+ }
+
+ string id = current.attributes.get ("id");
+ if (id != null) {
+ id_registrar.register_symbol (id, element);
+ }
+ next ();
+
- private LinkedList<Block>? parse_docbook_variablelist () {
++ Vala.Collection<Block> content = parse_mixed_content ();
+
+ if (!check_xml_close_tag ("section")) {
+ this.report_unexpected_token (current, "</section>");
+ return content;
+ }
+
+ next ();
+ return content;
+ }
+
+ private ListItem? parse_docbook_member () {
+ if (!check_xml_open_tag ("member")) {
+ this.report_unexpected_token (current, "<member>");
+ return null;
+ }
+ next ();
+
+ parse_docbook_spaces ();
+
+ ListItem item = factory.create_list_item ();
+ Paragraph para = factory.create_paragraph ();
+ item.content.add (para);
+
+ para.content.add (parse_inline_content ());
+
+ parse_docbook_spaces ();
+
+ if (!check_xml_close_tag ("member")) {
+ this.report_unexpected_token (current, "</member>");
+ return item;
+ }
+
+ next ();
+ return item;
+ }
+
+ private Content.List? parse_docbook_simplelist () {
+ if (!check_xml_open_tag ("simplelist")) {
+ this.report_unexpected_token (current, "<simplelist>");
+ return null;
+ }
+ next ();
+
+ parse_docbook_spaces ();
+
+ Content.List list = factory.create_list ();
+
+ while (current.type == TokenType.XML_OPEN && current.content == "member") {
+ ListItem item = parse_docbook_member ();
+ if (item == null) {
+ break;
+ }
+
+ list.items.add (item);
+ parse_docbook_spaces ();
+ }
+
+
+ if (!check_xml_close_tag ("simplelist")) {
+ this.report_unexpected_token (current, "</simplelist>");
+ return list;
+ }
+
+ next ();
+ return list;
+ }
+
+ private Paragraph? parse_docbook_term () {
+ if (!check_xml_open_tag ("term")) {
+ this.report_unexpected_token (current, "<term>");
+ return null;
+ }
+ next ();
+
+ parse_docbook_spaces ();
+
+ Paragraph? p = factory.create_paragraph ();
+ Run run = parse_inline_content ();
+ run.style = Run.Style.ITALIC;
+ p.content.add (run);
+
+ if (!check_xml_close_tag ("term")) {
+ this.report_unexpected_token (current, "</term>");
+ return p;
+ }
+
+ next ();
+ return p;
+ }
+
+ private ListItem? parse_docbook_varlistentry () {
+ if (!check_xml_open_tag ("varlistentry")) {
+ this.report_unexpected_token (current, "<varlistentry>");
+ return null;
+ }
+ next ();
+
+ parse_docbook_spaces ();
+
+ if (current.type != TokenType.XML_OPEN || current.content != "term") {
+ return null;
+ }
+
+ Paragraph? term = parse_docbook_term ();
+ if (term == null) {
+ return null;
+ }
+
+ parse_docbook_spaces ();
+ ListItem? desc = parse_docbook_listitem ();
+ if (desc == null) {
+ return null;
+ }
+
+ parse_docbook_spaces ();
+
+ Content.ListItem listitem = factory.create_list_item ();
+ Content.List list = factory.create_list ();
+
+ listitem.content.add (term);
+ listitem.content.add (list);
+ list.items.add (desc);
+
+ if (!check_xml_close_tag ("varlistentry")) {
+ this.report_unexpected_token (current, "</varlistentry>");
+ return listitem;
+ }
+
+ next ();
+ return listitem;
+ }
+
- LinkedList<Block> content = new LinkedList<Block> ();
++ private Vala.Collection<Block>? parse_docbook_variablelist () {
+ if (!check_xml_open_tag ("variablelist")) {
+ this.report_unexpected_token (current, "<variablelist>");
+ return null;
+ }
+ next ();
+
+ parse_docbook_spaces ();
+
- private LinkedList<Block> parse_block_content () {
- LinkedList<Block> content = new LinkedList<Block> ();
++ Vala.Collection<Block> content = new Vala.ArrayList<Block> ();
+
+ if (current.type == TokenType.XML_OPEN && current.content == "title") {
+ append_block_content_not_null (content, parse_docbook_title ());
+ parse_docbook_spaces ();
+ }
+
+ Content.List list = factory.create_list ();
+ content.add (list);
+
+ while (current.type == TokenType.XML_OPEN && current.content == "varlistentry") {
+ ListItem item = parse_docbook_varlistentry ();
+ if (item == null) {
+ break;
+ }
+
+ list.items.add (item);
+ parse_docbook_spaces ();
+ }
+
+ if (!check_xml_close_tag ("variablelist")) {
+ this.report_unexpected_token (current, "</variablelist>");
+ return content;
+ }
+
+ next ();
+ return content;
+ }
+
++ private Vala.Collection<Block> parse_block_content () {
++ Vala.Collection<Block> content = new Vala.ArrayList<Block> ();
+
+ while (current.type != TokenType.EOF) {
+ parse_docbook_spaces (false);
+
+ if (current.type == TokenType.XML_OPEN && current.content == "itemizedlist") {
+ this.append_block_content_not_null_all (content, parse_docbook_itemizedlist ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "orderedlist") {
+ this.append_block_content_not_null_all (content, parse_docbook_orderedlist ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "variablelist") {
+ this.append_block_content_not_null_all (content, parse_docbook_variablelist ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "simplelist") {
+ this.append_block_content_not_null (content, parse_docbook_simplelist ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "informaltable") {
+ this.append_block_content_not_null (content, parse_docbook_informaltable ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "programlisting") {
+ this.append_block_content_not_null (content, parse_docbook_programlisting ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "para") {
+ this.append_block_content_not_null_all (content, parse_docbook_para ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "simpara") {
+ this.append_block_content_not_null_all (content, parse_docbook_simpara ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "informalexample") {
+ this.append_block_content_not_null_all (content, parse_docbook_informalexample ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "example") {
+ this.append_block_content_not_null_all (content, parse_docbook_example ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "warning") {
+ this.append_block_content_not_null (content, parse_docbook_warning ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "note") {
+ this.append_block_content_not_null (content, parse_docbook_note ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "important") {
+ this.append_block_content_not_null (content, parse_docbook_important ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "refsect3") {
+ this.append_block_content_not_null_all (content, parse_docbook_refsect2 (3));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "refsect2") {
+ this.append_block_content_not_null_all (content, parse_docbook_refsect2 ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "figure") {
+ this.append_block_content_not_null_all (content, parse_docbook_figure ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "title") {
+ this.append_block_content_not_null (content, parse_docbook_title ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "section") {
+ this.append_block_content_not_null_all (content, parse_docbook_section ());
+ } else if (current.type == TokenType.GTKDOC_PARAGRAPH) {
+ this.append_block_content_not_null (content, parse_gtkdoc_paragraph ());
+ } else if (current.type == TokenType.GTKDOC_SOURCE_OPEN) {
+ this.append_block_content_not_null (content, parse_gtkdoc_source ());
+ } else {
+ break;
+ }
+ }
+
+ return content;
+ }
+
+ private Run? parse_xml_tag () {
+ if (!check_xml_open_tag ("tag")) {
+ this.report_unexpected_token (current, "<tag>");
+ return null;
+ }
+ string? _class = current.attributes.get ("class");
+ next ();
+
+ parse_docbook_spaces (false);
+
+ if (current.type != TokenType.WORD) {
+ this.report_unexpected_token (current, "<WORD>");
+ return null;
+ }
+
+ Run run = factory.create_run (Run.Style.MONOSPACED);
+ if (_class == null || _class == "starttag") {
+ run.content.add (factory.create_text ("<" + current.content + ">"));
+ next ();
+ } else if (_class == "endtag") {
+ run.content.add (factory.create_text ("</" + current.content + ">"));
+ next ();
+ } else {
+ this.report_unexpected_token (current, "<tag class=\"%s\">".printf (_class));
+ return run;
+ }
+
+ parse_docbook_spaces (false);
+
+
+ if (!check_xml_close_tag ("tag")) {
+ this.report_unexpected_token (current, "</tag>");
+ return run;
+ }
+
+ next ();
+ return run;
+ }
+
+ private void append_inline_content_string (Run run, string current) {
+ Text last_as_text = null;
+
+ if (run.content.size > 0) {
+ last_as_text = run.content.last () as Text;
+ }
+
+ if (last_as_text == null) {
+ run.content.add (factory.create_text (current));
+ } else if (current.has_prefix (" ") && last_as_text.content.has_suffix (" ")) {
+ last_as_text.content += current.chug ();
+ } else {
+ last_as_text.content += current;
+ }
+ }
+
+ private Inline create_type_link (string name, bool c_accept_plural = false) {
+ if (name == "TRUE" || name == "FALSE" || name == "NULL" || is_numeric (name)) {
+ var monospaced = factory.create_run (Run.Style.MONOSPACED);
+ monospaced.content.add (factory.create_text (name.down ()));
+ return monospaced;
+ } else {
+ Taglets.Link? taglet = factory.create_taglet ("link") as Taglets.Link;
+ assert (taglet != null);
+ taglet.c_accept_plural = c_accept_plural;
+ taglet.symbol_name = "c::"+name;
+ return taglet;
+ }
+ }
+
+ private inline void append_inline_content_not_null (Run run, Inline element) {
+ if (element != null) {
+ run.content.add (element);
+ }
+ }
+
+ private Run parse_inline_content () {
+ Run run = factory.create_run (Run.Style.NONE);
+
+ while (current.type != TokenType.EOF) {
+ if (current.type == TokenType.XML_OPEN && current.content == "firstterm") {
+ append_inline_content_not_null (run, parse_highlighted_template ("firstterm", Run.Style.ITALIC));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "abbrev") {
+ append_inline_content_not_null (run, parse_highlighted_template ("abbrev", Run.Style.ITALIC));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "term") {
+ append_inline_content_not_null (run, parse_highlighted_template ("term", Run.Style.ITALIC));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "literal") {
+ append_inline_content_not_null (run, parse_highlighted_template ("literal", Run.Style.ITALIC));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "literallayout") {
+ append_inline_content_not_null (run, parse_highlighted_template ("literallayout", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "application") {
+ append_inline_content_not_null (run, parse_highlighted_template ("application", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "varname") {
+ append_inline_content_not_null (run, parse_highlighted_template ("varname", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "computeroutput") {
+ append_inline_content_not_null (run, parse_highlighted_template ("computeroutput", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "emphasis") {
+ append_inline_content_not_null (run, parse_highlighted_template ("emphasis", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "pre") {
+ append_inline_content_not_null (run, parse_highlighted_template ("pre", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "code") {
+ append_inline_content_not_null (run, parse_highlighted_template ("code", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "guimenuitem") {
+ append_inline_content_not_null (run, parse_highlighted_template ("guimenuitem", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "command") {
+ append_inline_content_not_null (run, parse_highlighted_template ("command", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "option") {
+ append_inline_content_not_null (run, parse_highlighted_template ("option", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "keycap") {
+ append_inline_content_not_null (run, parse_highlighted_template ("keycap", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "keycombo") {
+ append_inline_content_not_null (run, parse_highlighted_template ("keycombo", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "envar") {
+ append_inline_content_not_null (run, parse_highlighted_template ("envar", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "filename") {
+ append_inline_content_not_null (run, parse_highlighted_template ("filename", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "parameter") {
+ append_inline_content_not_null (run, parse_highlighted_template ("parameter", Run.Style.MONOSPACED));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "replaceable") {
+ append_inline_content_not_null (run, parse_highlighted_template ("replaceable", Run.Style.ITALIC));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "quote") {
+ run.content.add (factory.create_text ("“"));
+ append_inline_content_not_null (run, parse_highlighted_template ("quote", Run.Style.NONE));
+ run.content.add (factory.create_text ("”"));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "footnote") {
+ append_inline_content_not_null (run, parse_docbook_footnote ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "type") {
+ append_inline_content_not_null (run, parse_symbol_link ("type"));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "function") {
+ append_inline_content_not_null (run, parse_symbol_link ("function"));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "classname") {
+ append_inline_content_not_null (run, parse_symbol_link ("classname"));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "structname") {
+ append_inline_content_not_null (run, parse_symbol_link ("structname"));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "structfield") {
+ append_inline_content_not_null (run, parse_symbol_link ("structfield"));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "errorcode") {
+ append_inline_content_not_null (run, parse_symbol_link ("errorcode"));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "constant") {
+ append_inline_content_not_null (run, parse_symbol_link ("constant"));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "inlinegraphic") {
+ append_inline_content_not_null (run, parse_docbook_inlinegraphic ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "anchor") {
+ parse_anchor ();
+ } else if (current.type == TokenType.XML_OPEN && current.content == "link") {
+ append_inline_content_not_null (run, parse_docbook_link_tempalte ("link", true));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "ulink") {
+ append_inline_content_not_null (run, parse_docbook_link_tempalte ("ulink", false));
+ } else if (current.type == TokenType.XML_OPEN && current.content == "xref") {
+ append_inline_content_not_null (run, parse_xref ());
+ } else if (current.type == TokenType.XML_OPEN && current.content == "tag") {
+ append_inline_content_not_null (run, parse_xml_tag ());
+ } else if (current.type == TokenType.GTKDOC_FUNCTION) {
+ run.content.add (this.create_type_link (current.content));
+ next ();
+ } else if (current.type == TokenType.GTKDOC_PARAM) {
+ if (current.content == instance_param_name) {
+ Content.Run keyword_run = factory.create_run (Content.Run.Style.LANG_KEYWORD);
+ Content.Text text = factory.create_text ("this");
+ keyword_run.content.add (text);
+ run.content.add (keyword_run);
+ } else {
+ string? param_array_name;
+ bool is_return_type_len;
+ string? param_name;
+
+ string? cname = ImporterHelper.resolve_parameter_ctype (
+ this.tree,
+ this.element,
+ current.content,
+ out param_name,
+ out param_array_name,
+ out is_return_type_len);
+
+ Run current_run = factory.create_run (Run.Style.MONOSPACED);
+ run.content.add (current_run);
+
+ if (is_return_type_len) {
+ Run keyword_run = factory.create_run (Run.Style.LANG_KEYWORD);
+ keyword_run.content.add (factory.create_text ("return"));
+ current_run.content.add (keyword_run);
+
+ current_run.content.add (factory.create_text (".length"));
+ } else if (param_array_name != null) {
+ current_run.content.add (factory.create_text (param_array_name + ".length"));
+ } else {
+ current_run.content.add (factory.create_text (param_name));
+ }
+
+ if (cname != null) {
+ run.content.add (factory.create_text ("."));
+
+ Taglets.Link link = factory.create_taglet ("link") as Taglets.Link;
+ link.symbol_name = cname;
+ run.content.add (link);
+ }
+ }
+ next ();
+ } else if (current.type == TokenType.GTKDOC_SIGNAL) {
+ run.content.add (this.create_type_link ("::" + current.content, true));
+ next ();
+ } else if (current.type == TokenType.GTKDOC_PROPERTY) {
+ run.content.add (this.create_type_link (":" + current.content, true));
+ next ();
+ } else if (current.type == TokenType.GTKDOC_CONST) {
+ run.content.add (this.create_type_link (current.content, true));
+ next ();
+ } else if (current.type == TokenType.GTKDOC_TYPE) {
+ run.content.add (this.create_type_link (current.content, true));
+ next ();
+ } else if (current.type == TokenType.NEWLINE || current.type == TokenType.SPACE) {
+ append_inline_content_string (run, " ");
+ next ();
+ } else if (current.type == TokenType.WORD) {
+ append_inline_content_string (run, current.content);
+ next ();
+ } else if (current.type == TokenType.XML_CLOSE && ignore_current_xml_close ()) {
+ next ();
+ } else if (current.type == TokenType.XML_COMMENT) {
+ next ();
+ } else {
+ break;
+ }
+ }
+
+ return run;
+ }
+
+
+
+ //
+ // Resource Locator:
+ //
+
+ public string resolve (string path) {
+ return path;
+ }
+ }
+
+
--- /dev/null
-using Gee;
-
-
+ /* gtkcommentscanner.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Gtkdoc;
- public HashMap<string, string>? attributes;
+
+ public enum Valadoc.Gtkdoc.TokenType {
+ XML_OPEN,
+ XML_CLOSE,
+ XML_COMMENT,
+ GTKDOC_FUNCTION,
+ GTKDOC_CONST,
+ GTKDOC_TYPE,
+ GTKDOC_PARAM,
+ GTKDOC_SOURCE_OPEN,
+ GTKDOC_SOURCE_CLOSE,
+ GTKDOC_SIGNAL,
+ GTKDOC_PROPERTY,
+ GTKDOC_PARAGRAPH,
+ NEWLINE,
+ SPACE,
+ WORD,
+ EOF
+ }
+
+
+ public class Valadoc.Gtkdoc.Token {
+ public TokenType type;
+ public string content;
- public Token (TokenType type, string content, HashMap<string, string>? attributes, string start,
++ public Vala.HashMap<string, string>? attributes;
+ public unowned string start;
+ public int length;
+ public int line;
+ public int first_column;
+ public int last_column;
+
- HashMap<string, string> map = new HashMap<string, string> ();
++ public Token (TokenType type, string content, Vala.HashMap<string, string>? attributes, string start,
+ int length, int line, int first_column, int last_column)
+ {
+ this.attributes = attributes;
+ this.content = content;
+ this.length = length;
+ this.start = start;
+ this.type = type;
+ this.line = line;
+ this.first_column = first_column;
+ this.last_column = last_column;
+ }
+
+ public string to_string () {
+ switch (this.type) {
+ case TokenType.XML_OPEN:
+ return "`<%s>'".printf (this.content);
+
+ case TokenType.XML_CLOSE:
+ return "`</%s>'".printf (this.content);
+
+ case TokenType.XML_COMMENT:
+ return "<XML-COMMENT>";
+
+ case TokenType.GTKDOC_FUNCTION:
+ return "`%s ()'".printf (this.content);
+
+ case TokenType.GTKDOC_CONST:
+ return "`%%%s'".printf (this.content);
+
+ case TokenType.GTKDOC_TYPE:
+ return "`#%s'".printf (this.content);
+
+ case TokenType.GTKDOC_PARAM:
+ return "<GTKDOC-PARAM>";
+
+ case TokenType.GTKDOC_SOURCE_OPEN:
+ return "[|";
+
+ case TokenType.GTKDOC_SOURCE_CLOSE:
+ return "|]";
+
+ case TokenType.GTKDOC_SIGNAL:
+ return "`::%s'".printf (this.content);
+
+ case TokenType.GTKDOC_PROPERTY:
+ return "`:%s'".printf (this.content);
+
+ case TokenType.GTKDOC_PARAGRAPH:
+ return "<GKTDOC-PARAGRAPH>";
+
+ case TokenType.NEWLINE:
+ return "<NEWLNIE>";
+
+ case TokenType.SPACE:
+ return "<SPACE>";
+
+ case TokenType.WORD:
+ return "`%s'".printf (this.content);
+
+ case TokenType.EOF:
+ return "<EOF>";
+
+ default:
+ assert_not_reached ();
+ }
+ }
+ }
+
+
+ public class Valadoc.Gtkdoc.Scanner {
+ private unowned string content;
+ private unowned string pos;
+ private int column;
+ private int line;
+ private Token tmp_token;
+
+ public Scanner () {
+ }
+
+ public static string unescape (string txt) {
+ StringBuilder builder = new StringBuilder ();
+ unowned string start = txt;
+ unowned string pos;
+ unichar c;
+
+ for (pos = txt; (c = pos.get_char ()) != '\0'; pos = pos.next_char ()) {
+ if (c == '&') {
+ if (pos.has_prefix ("&solidus;")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 9);
+ pos = (string) ((char*) pos + 8);
+ builder.append_unichar ('⁄');
+ } else if (pos.has_prefix ("%")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 8);
+ pos = (string) ((char*) pos + 7);
+ builder.append_c ('%');
+ } else if (pos.has_prefix ("@")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 8);
+ pos = (string) ((char*) pos + 7);
+ builder.append_c ('@');
+ } else if (pos.has_prefix (" ")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 6);
+ pos = (string) ((char*) pos + 5);
+ builder.append_c (' ');
+ } else if (pos.has_prefix (""")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 6);
+ pos = (string) ((char*) pos + 5);
+ builder.append_c ('"');
+ } else if (pos.has_prefix ("'")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 6);
+ pos = (string) ((char*) pos + 5);
+ builder.append_c ('\'');
+ } else if (pos.has_prefix ("(")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 6);
+ pos = (string) ((char*) pos + 5);
+ builder.append_c ('(');
+ } else if (pos.has_prefix (")")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 6);
+ pos = (string) ((char*) pos + 5);
+ builder.append_c (')');
+ } else if (pos.has_prefix ("#")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 5);
+ pos = (string) ((char*) pos + 4);
+ builder.append_c ('#');
+ } else if (pos.has_prefix ("&")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 5);
+ pos = (string) ((char*) pos + 4);
+ builder.append_c ('&');
+ } else if (pos.has_prefix ("*")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 5);
+ pos = (string) ((char*) pos + 4);
+ builder.append_c ('*');
+ } else if (pos.has_prefix ("π")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 4);
+ pos = (string) ((char*) pos + 3);
+ builder.append_unichar ('π');
+ } else if (pos.has_prefix ("<")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 4);
+ pos = (string) ((char*) pos + 3);
+ builder.append_c ('<');
+ } else if (pos.has_prefix (">")) {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ start = (string) ((char*) pos + 4);
+ pos = (string) ((char*) pos + 3);
+ builder.append_c ('>');
+ }
+ }
+ }
+
+ if (&txt == &start) {
+ return txt;
+ } else {
+ builder.append_len (start, (ssize_t) ((char*) pos - (char*) start));
+ return (owned) builder.str;
+ }
+ }
+
+ public void reset (string content) {
+ this.content = content;
+ this.tmp_token = null;
+ this.pos = content;
+ this.column = 0;
+ this.line = 0;
+ }
+
+ private inline unichar next_char () {
+ this.pos = this.pos.next_char ();
+ this.column++;
+
+ return this.pos.get_char ();
+ }
+
+ private inline unichar get () {
+ return this.pos.get_char ();
+ }
+
+ private inline bool letter (unichar c) {
+ return (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z');
+ }
+
+ private inline bool letter_or_number (unichar c) {
+ return (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9');
+ }
+
+ private inline bool space (unichar c) {
+ return c == ' ' || c == '\t';
+ }
+
+ private inline bool space_or_newline (unichar c) {
+ if (c == '\n') {
+ this.line++;
+ this.column = 0;
+ return true;
+ }
+
+ return space (c);
+ }
+
+ private inline int offset (string a, string b) {
+ return (int) ((char*) a - (char*) b);
+ }
+
+ private inline int vararg_prefix () {
+ if (this.pos.has_prefix ("...")) {
+ next_char ();
+ next_char ();
+ next_char ();
+ return 3;
+ }
+
+ return 0;
+ }
+
+ private inline int id_prefix () {
+ unichar c = get ();
+
+ if (!letter (c) && c != '_') {
+ return 0;
+ }
+
+ int start = this.column;
+ while ((c = next_char ()) == '_' || letter_or_number (c));
+ return this.column - start;
+ }
+
+ private inline int g_id_prefix () {
+ unowned string start = this.pos;
+ unichar c = get ();
+
+ if (!letter (c)) {
+ return 0;
+ }
+
+ while ((c = next_char ()) == '_' || c == '-' || letter_or_number (c));
+ return offset (this.pos, start);
+ }
+
+ private inline int skip_spaces_and_newlines () {
+ unowned string start = this.pos;
+ if (space_or_newline (get ())) {
+ while (space_or_newline (next_char ()));
+ }
+
+ return offset (this.pos, start);
+ }
+
+ private inline Token? function_prefix () {
+ unowned string start = this.pos;
+ int column_start = this.column;
+ int id_len = 0;
+
+ if ((id_len = id_prefix ()) == 0) {
+ return null;
+ }
+
+ space_prefix ();
+
+ if (get () != '(') {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+ next_char ();
+ space_prefix ();
+
+ if (get () != ')') {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+ next_char ();
+ return new Token (TokenType.GTKDOC_FUNCTION,
+ start.substring (0, id_len),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ private inline Token? gtkdoc_symbolic_link_prefix (unichar c, TokenType type) {
+ if (get () != c) {
+ return null;
+ }
+
+ unowned string start = this.pos;
+ int column_start = this.column;
+ next_char ();
+
+ int id_len = 0;
+
+ if ((id_len = id_prefix ()) == 0) {
+ if (type == TokenType.GTKDOC_PARAM && (id_len = vararg_prefix ()) == 0) {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+ }
+
+ unowned string separator = this.pos;
+ if (get () == ':') {
+ int separator_len = 1;
+ if (next_char () == ':') {
+ next_char ();
+ separator_len++;
+ }
+
+ int id_len2;
+ if ((id_len2 = g_id_prefix ()) == 0) {
+ this.pos = separator;
+ } else {
+ id_len += id_len2 + separator_len;
+ }
+ } else if (this.pos.has_prefix ("->") || this.pos.has_prefix (".")) {
+ unowned string sep_start = this.pos;
+ int sep_column_start = this.column;
+ int separator_len = 1;
+
+ if (this.pos.has_prefix ("->")) {
+ separator_len = 2;
+ next_char ();
+ }
+
+ next_char ();
+
+ Token? func_token = function_prefix ();
+ if (func_token == null) {
+ int id_len2;
+
+ if ((id_len2 = id_prefix ()) > 0) {
+ id_len += separator_len + id_len2;
+ } else {
+ this.column = sep_column_start;
+ this.pos = sep_start;
+ }
+ } else {
+ id_len += separator_len + func_token.content.length;
+ }
+ }
+
+ return new Token (type,
+ start.substring (1, id_len),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ private inline Token? gtkdoc_property_prefix () {
+ if (get () != ':') {
+ return null;
+ }
+
+ unowned string start = this.pos;
+ int column_start = this.column;
+ next_char ();
+
+ int id_len = 0;
+
+ if ((id_len = g_id_prefix ()) == 0) {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+ return new Token (TokenType.GTKDOC_PROPERTY,
+ start.substring (1, id_len),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ private inline Token? gtkdoc_signal_prefix () {
+ if (get () != ':') {
+ return null;
+ }
+
+ unowned string start = this.pos;
+ int column_start = this.column;
+ if (next_char () != ':') {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+
+ start = this.pos;
+ next_char ();
+
+ int id_len = 0;
+
+ if ((id_len = g_id_prefix ()) == 0) {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+ return new Token (TokenType.GTKDOC_SIGNAL,
+ start.substring (1, id_len),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ private inline Token? gtkdoc_const_prefix () {
+ return gtkdoc_symbolic_link_prefix ('%', TokenType.GTKDOC_CONST);
+ }
+
+ private inline Token? gtkdoc_param_prefix () {
+ return gtkdoc_symbolic_link_prefix ('@', TokenType.GTKDOC_PARAM);
+ }
+
+ private inline Token? gtkdoc_type_prefix () {
+ return gtkdoc_symbolic_link_prefix ('#', TokenType.GTKDOC_TYPE);
+ }
+
+ private inline Token? xml_prefix () {
+ if (get () != '<') {
+ return null;
+ }
+
+ unowned string start = this.pos;
+ int line_start = this.line;
+ int column_start = this.column;
+ next_char ();
+
+ if (get () == '!') {
+ // comment
+ if (next_char () == '-') {
+ if (next_char () != '-') {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+ for (unichar c = next_char (); c != '\0'; c = next_char ()) {
+ if (c == '\n') {
+ this.line++;
+ this.column = 0;
+ } else if (this.pos.has_prefix ("-->")) {
+ next_char ();
+ next_char ();
+ next_char ();
+ return new Token (TokenType.XML_COMMENT,
+ "",
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+ }
+ } else if (this.pos.has_prefix ("[CDATA[")) {
+ next_char ();
+ next_char ();
+ next_char ();
+ next_char ();
+ next_char ();
+ next_char ();
+
+ for (unichar c = next_char (); c != '\0'; c = next_char ()) {
+ if (c == '\n') {
+ this.line++;
+ this.column = 0;
+ } else if (this.pos.has_prefix ("]]>")) {
+ string content = start.substring (9, offset (this.pos, start) - 9);
+ next_char ();
+ next_char ();
+ next_char ();
+ return new Token (TokenType.WORD,
+ unescape (content),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+ }
+ }
+
+ this.pos = start;
+ this.column = column_start;
+ this.line = line_start;
+ return null;
+ }
+
+ bool close = false;
+ if (get () == '/') {
+ next_char ();
+ close = true;
+ }
+
+ unowned string id_start = this.pos;
+
+ int id_len = 0;
+ if ((id_len = id_prefix ()) == 0) {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
++ Vala.HashMap<string, string> map = new Vala.HashMap<string, string> (str_hash, str_equal);
+
+ while (close == false && skip_spaces_and_newlines () > 0) {
+ string name;
+ string val;
+
+ unowned string att_pos = this.pos;
+ int att_id_len = 0;
+ if ((att_id_len = id_prefix ()) == 0) {
+ break;
+ }
+
+ name = att_pos.substring (0, att_id_len);
+
+ if (get() != '=') {
+ break;
+ }
+
+ next_char ();
+ skip_spaces_and_newlines ();
+
+ if (get() != '"') {
+ break;
+ }
+
+ unichar c = next_char ();
+ att_pos = this.pos;
+ for (; c != '\0' && c != '\n' && c != '"' ; c = next_char ());
+
+ val = att_pos.substring (0, offset (this.pos, att_pos));
+
+ if (get() != '"') {
+ break;
+ }
+
+ next_char ();
+
+ map.set (name, val);
+ }
+
+ skip_spaces_and_newlines ();
+
+ bool open_and_close = false;
+
+ if (!close && get () == '/') {
+ open_and_close = true;
+ next_char ();
+ }
+
+ if (get () != '>') {
+ this.line = line_start;
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+ next_char ();
+
+ if (open_and_close) {
+ this.tmp_token = new Token (TokenType.XML_CLOSE,
+ id_start.substring (0, id_len),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ if (close) {
+ return new Token (TokenType.XML_CLOSE,
+ id_start.substring (0, id_len),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ } else {
+ return new Token (TokenType.XML_OPEN,
+ id_start.substring (0, id_len),
+ map,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+ }
+
+ private Token? newline_prefix () {
+ if (get () != '\n') {
+ return null;
+ }
+
+ unowned string start = this.pos;
+ this.line++;
+ this.column = 0;
+
+ for (unichar c = next_char (); c == ' ' || c == '\t' ; c = next_char ());
+
+ if (get () == '\n') {
+ next_char ();
+ this.line++;
+ this.column = 0;
+ return new Token (TokenType.GTKDOC_PARAGRAPH,
+ "\n\n",
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ this.column,
+ this.column);
+ } else {
+ return new Token (TokenType.NEWLINE,
+ "\n",
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ this.column,
+ this.column);
+ }
+ }
+
+ private Token? eof_prefix () {
+ if (get () != '\0') {
+ return null;
+ }
+
+ return new Token (TokenType.EOF,
+ "",
+ null,
+ this.pos,
+ 1,
+ this.line,
+ this.column,
+ this.column);
+ }
+
+ private Token? space_prefix () {
+ unowned string start = this.pos;
+ int column_start = this.column;
+ for (unichar c = get (); c == ' ' || c == '\t'; c = next_char ());
+ int len = offset (this.pos, start);
+ if (len == 0) {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+ return new Token (TokenType.SPACE,
+ start.substring (0, len),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ private Token? word_prefix () {
+ unowned string start = this.pos;
+ int column_start = this.column;
+ unichar c = get ();
+ if (c == '<' || c == '@') {
+ next_char ();
+ }
+
+ for (c = get (); c != ' ' && c != '\t' && c != '\n' && c != '\0' && c != '<' && c != '@'; c = next_char ());
+ int len = offset (this.pos, start);
+ if (len == 0) {
+ this.column = column_start;
+ this.pos = start;
+ return null;
+ }
+
+ return new Token (TokenType.WORD,
+ unescape (start.substring (0, len)),
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ private Token? gtkdoc_source_open_prefix () {
+ if (!this.pos.has_prefix ("|[")) {
+ return null;
+ }
+
+ unowned string start = this.pos;
+ int column_start = this.column;
+ next_char ();
+ next_char ();
+
+ return new Token (TokenType.GTKDOC_SOURCE_OPEN,
+ "|[",
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ private Token? gtkdoc_source_close_prefix () {
+ if (!this.pos.has_prefix ("]|")) {
+ return null;
+ }
+
+ unowned string start = this.pos;
+ int column_start = this.column;
+ next_char ();
+ next_char ();
+
+ return new Token (TokenType.GTKDOC_SOURCE_CLOSE, "]|",
+ null,
+ start,
+ offset (this.pos, start),
+ this.line,
+ column_start,
+ this.column);
+ }
+
+ public Token next () {
+ if (tmp_token != null) {
+ var tmp = tmp_token;
+ tmp_token = null;
+ return tmp;
+ }
+
+ Token? token = function_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = xml_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = gtkdoc_param_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = gtkdoc_const_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = gtkdoc_type_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = space_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = newline_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = gtkdoc_signal_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = gtkdoc_property_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = gtkdoc_source_open_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = gtkdoc_source_close_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = eof_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ token = word_prefix ();
+ if (token != null) {
+ return token;
+ }
+
+ assert_not_reached ();
+ }
+ }
+
--- /dev/null
-using Gee;
-
-
+ /* gtkdocmarkdownparser.vala
+ *
+ * Copyright (C) 2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Content;
+ using Valadoc;
- private ArrayList<Object> _stack = new ArrayList<Object> ();
+
+ public class Valadoc.Gtkdoc.MarkdownParser : Object, ResourceLocator {
+ private Valadoc.Parser parser;
+ private Content.ContentFactory _factory;
+
+ private Settings _settings;
+ private ErrorReporter _reporter;
+ private Api.Tree _tree;
+
- MapIterator<string, Api.SourceComment> iter = gir_comment.parameter_iterator ();
++ private Vala.ArrayList<Object> _stack = new Vala.ArrayList<Object> ();
+
+ private Valadoc.Token preserved_token = null;
+ private Regex regex_source_lang;
+
+ private Importer.InternalIdRegistrar id_registrar;
+ private GirMetaData metadata;
+ private Api.GirSourceComment gir_comment;
+ private Api.Node element;
+
+
+ public MarkdownParser (Settings settings, ErrorReporter reporter, Api.Tree? tree, ModuleLoader _modules) {
+ MarkdownScanner scanner = new MarkdownScanner (settings);
+ parser = new Valadoc.Parser (settings, scanner, reporter);
+ scanner.set_parser (parser);
+
+
+ _factory = new Content.ContentFactory (settings, this, _modules);
+ _settings = settings;
+ _reporter = reporter;
+ _tree = tree;
+
+ init_rules ();
+
+ try {
+ regex_source_lang = new Regex ("^<!--[ \t]+language=\"([A-Za-z]*)\"[ \t]+-->");
+ } catch (Error e) {
+ assert_not_reached ();
+ }
+ }
+
+ public void init_rules () {
+ Valadoc.TokenType word = Valadoc.TokenType.any_word ().action (add_text);
+
+ StubRule content = new StubRule ();
+ content.set_name ("Content");
+
+ StubRule run = new StubRule ();
+ run.set_name ("Run");
+
+
+ Rule param = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_PARAMETER.action ((token) => {
+ Run _run = null;
+
+ if (token.value == gir_comment.instance_param_name) {
+ _run = _factory.create_run (Run.Style.LANG_KEYWORD);
+ _run.content.add (_factory.create_text ("this"));
+ } else if (is_error_parameter (token.value)) {
+ _run = _factory.create_run (Run.Style.LANG_KEYWORD);
+ _run.content.add (_factory.create_text ("throws"));
+ } else {
+ string? param_name;
+ string? param_array_name;
+ bool is_return_type_len;
+
+ ImporterHelper.resolve_parameter_ctype (
+ this._tree,
+ this.element,
+ token.value,
+ out param_name,
+ out param_array_name,
+ out is_return_type_len);
+
+ _run = _factory.create_run (Run.Style.MONOSPACED);
+
+ if (is_return_type_len) {
+ Run keyword_run = _factory.create_run (Run.Style.LANG_KEYWORD);
+ keyword_run.content.add (_factory.create_text ("return"));
+ _run.content.add (keyword_run);
+
+ _run.content.add (_factory.create_text (".length"));
+ } else if (param_array_name != null) {
+ _run.content.add (_factory.create_text (param_array_name + ".length"));
+ } else {
+ _run.content.add (_factory.create_text (param_name));
+ }
+
+
+ }
+
+ push (_run);
+ })
+ })
+ .set_name ("Parameter");
+
+
+ Rule constant = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_CONSTANT.action ((token) => {
+ if (is_literal (token.value)) {
+ var _run = _factory.create_run (Run.Style.LANG_LITERAL);
+ _run.content.add (_factory.create_text (token.value.down ()));
+ push (_run);
+ } else {
+ add_symbol_link ("c::" + token.value, true);
+ }
+ })
+ })
+ .set_name ("Constant");
+
+
+ Rule gmember = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_LOCAL_GMEMBER.action ((token) => {
+ Api.Item gtype = element;
+ while (gtype is Api.Class == false && gtype is Api.Interface == false && gtype != null) {
+ gtype = gtype.parent;
+ }
+
+ string parent_cname;
+ if (gtype is Api.Class) {
+ parent_cname = ((Api.Class) gtype).get_cname ();
+ } else if (gtype is Api.Interface) {
+ parent_cname = ((Api.Interface) gtype).get_cname ();
+ } else {
+ parent_cname = "";
+ }
+
+ add_symbol_link ("c::" + parent_cname + token.value, true);
+ })
+ })
+ .set_name ("GLocalMember");
+
+
+ Rule symbol = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_SYMBOL.action ((token) => {
+ add_symbol_link ("c::" + token.value, true);
+ })
+ })
+ .set_name ("Symbol");
+
+
+ Rule function = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_FUNCTION.action ((token) => {
+ add_symbol_link ("c::" + token.value, false);
+ })
+ })
+ .set_name ("Function");
+
+
+ Rule link_short = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_LESS_THAN,
+ Rule.option ({
+ Rule.one_of ({
+ Valadoc.TokenType.MARKDOWN_MAIL.action (preserve_token),
+ Valadoc.TokenType.MARKDOWN_LINK.action (preserve_token)
+ }),
+ Rule.option ({
+ Valadoc.TokenType.MARKDOWN_GREATER_THAN,
+ })
+ .set_reduce (() => {
+ Link url = _factory.create_link ();
+ url.url = pop_preserved_link ();
+ push (url);
+ })
+ .set_skip (() => {
+ add_content_string ("<");
+ add_value (preserved_token);
+ preserved_token = null;
+ })
+ })
+ .set_skip (() => {
+ add_content_string ("<");
+ })
+ })
+ .set_name ("Link");
+
+
+ Rule link = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_OPEN_BRACKET,
+ Rule.option ({
+ Rule.option ({
+ run
+ }),
+ Valadoc.TokenType.MARKDOWN_CLOSE_BRACKET,
+ Rule.option ({
+ Rule.one_of ({
+ // External link:
+ Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_OPEN_PARENS,
+ Rule.option ({
+ Rule.one_of ({
+ Valadoc.TokenType.MARKDOWN_LINK.action (preserve_token),
+ Valadoc.TokenType.MARKDOWN_MAIL.action (preserve_token)
+ }),
+ Rule.option ({
+ Valadoc.TokenType.MARKDOWN_CLOSE_PARENS
+ })
+ .set_reduce (() => {
+ Link url = _factory.create_link ();
+ url.url = pop_preserved_link ();
+
+ Run label = (Run) peek ();
+ url.content.add_all (label.content);
+ label.content.clear ();
+ label.content.add (url);
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("["));
+ _run.content.add (_factory.create_text ("](" + pop_preserved_link ()));
+ })
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("["));
+ _run.content.add (_factory.create_text ("]("));
+ })
+ }),
+ // Internal link:
+ Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_OPEN_BRACKET,
+ Rule.option ({
+ Valadoc.TokenType.any_word ().action (preserve_token),
+ Rule.option ({
+ Valadoc.TokenType.MARKDOWN_CLOSE_BRACKET
+ })
+ .set_reduce (() => {
+ Link url = _factory.create_link ();
+ url.url = pop_preserved_link ();
+ url.id_registrar = id_registrar;
+
+ Run label = (Run) peek ();
+ url.content.add_all (label.content);
+ label.content.clear ();
+ label.content.add (url);
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("["));
+
+ _run.content.add (_factory.create_text ("][" + pop_preserved_link ()));
+ })
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("["));
+ _run.content.add (_factory.create_text ("]["));
+ })
+ })
+ })
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("["));
+ _run.content.add (_factory.create_text ("]"));
+ })
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("["));
+ })
+ })
+ .set_start (() => { push (_factory.create_run (Run.Style.NONE)); })
+ .set_name ("Link");
+
+
+ Rule image = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_EXCLAMATION_MARK,
+ Rule.option ({
+ Valadoc.TokenType.MARKDOWN_OPEN_BRACKET,
+ Rule.option ({
+ run
+ }),
+ Valadoc.TokenType.MARKDOWN_CLOSE_BRACKET,
+ Rule.option ({
+ Valadoc.TokenType.MARKDOWN_OPEN_BRACKET,
+ Rule.option ({
+ Rule.one_of ({
+ Valadoc.TokenType.any_word ().action (preserve_token),
+ Valadoc.TokenType.MARKDOWN_LINK.action (preserve_token),
+ Valadoc.TokenType.MARKDOWN_MAIL.action (preserve_token)
+ }),
+ Rule.option ({
+ Valadoc.TokenType.MARKDOWN_CLOSE_BRACKET,
+ })
+ .set_reduce (() => {
+ Run label = (Run) peek ();
+
+ string label_str;
+ try {
+ label_str = run_to_string (label, "<image>");
+ } catch (Error e) {
+ parser.warning (preserved_token, e.message);
+ label_str = null;
+ }
+
+ Embedded embedded = _factory.create_embedded ();
+ embedded.url = fix_resource_path (pop_preserved_path ());
+ embedded.caption = label_str;
+
+ label.content.clear ();
+ label.content.add (embedded);
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("!["));
+ _run.content.add (_factory.create_text ("][" + pop_preserved_link ()));
+ })
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("!["));
+ _run.content.add (_factory.create_text ("]["));
+ })
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("!["));
+ _run.content.add (_factory.create_text ("]"));
+ })
+ })
+ .set_skip (() => {
+ Run _run = (Run) peek ();
+ _run.content.insert (0, _factory.create_text ("!"));
+ })
+ })
+ .set_start (() => { push (_factory.create_run (Run.Style.NONE)); })
+ .set_name ("Image");
+
+
+ Rule source = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_SOURCE.action ((token) => {
+ SourceCode code = _factory.create_source_code ();
+ MatchInfo info;
+
+ unowned string source = token.value;
+ if (regex_source_lang.match (source, 0, out info)) {
+ string lang_name = info.fetch (1).down ();
+ SourceCode.Language? lang = SourceCode.Language.from_string (lang_name);
+ code.language = lang;
+
+ if (lang == null) {
+ parser.warning (token, "Unknown language `%s' in source code block |[<!-- language=\"\"".printf (lang_name));
+ }
+
+ source = source.offset (source.index_of_char ('>') + 1);
+ } else {
+ code.language = (Highlighter.XmlScanner.is_xml (source))
+ ? SourceCode.Language.XML
+ : SourceCode.Language.C;
+ }
+
+ code.code = source;
+ push (code);
+ })
+ })
+ .set_name ("Source");
+
+
+ Rule text = Rule.many ({
+ Rule.one_of ({
+ word,
+ Valadoc.TokenType.MARKDOWN_SPACE.action (add_text),
+ Valadoc.TokenType.MARKDOWN_MAIL.action (add_value),
+ Valadoc.TokenType.MARKDOWN_LINK.action (add_value),
+ Valadoc.TokenType.MARKDOWN_OPEN_PARENS.action (add_text),
+ Valadoc.TokenType.MARKDOWN_CLOSE_PARENS.action (add_text),
+ Valadoc.TokenType.MARKDOWN_CLOSE_BRACKET.action (add_text),
+ Valadoc.TokenType.MARKDOWN_GREATER_THAN.action (add_text)
+ })
+ })
+ .set_start (() => { push (_factory.create_text ()); })
+ .set_name ("Text");
+
+
+ run.set_rule (
+ Rule.many ({
+ Rule.one_of ({
+ text,
+ link,
+ link_short,
+ image,
+ function,
+ constant,
+ param,
+ symbol,
+ gmember,
+ source
+ })
+ .set_reduce (() => {
+ var head = (Inline) pop ();
+ ((InlineContent) peek ()).content.add (head);
+ })
+ })
+ );
+
+
+ Rule unordered_list = Rule.seq ({
+ Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_UNORDERED_LIST_ITEM_START,
+ content,
+ Valadoc.TokenType.MARKDOWN_UNORDERED_LIST_ITEM_END
+ })
+ .set_start (() => { push (_factory.create_list_item ()); })
+ .set_reduce (() => {
+ var head = (ListItem) pop ();
+ ((Content.List) peek ()).items.add (head);
+ })
+ })
+ .set_start (() => {
+ var siblings = ((BlockContent) peek ()).content;
+ if (siblings.size > 0 && siblings.last () is Content.List) {
+ push (siblings.last ());
+ } else {
+ Content.List list = _factory.create_list ();
+ list.bullet = Content.List.Bullet.UNORDERED;
+ siblings.add (list);
+ push (list);
+ }
+ })
+ .set_reduce (() => {
+ (Content.List) pop ();
+ })
+ .set_name ("UnorderedList");
+
+
+ Rule ordered_list = Rule.seq ({
+ Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_ORDERED_LIST_ITEM_START,
+ content,
+ Valadoc.TokenType.MARKDOWN_ORDERED_LIST_ITEM_END
+ })
+ .set_start (() => { push (_factory.create_list_item ()); })
+ .set_reduce (() => {
+ var head = (ListItem) pop ();
+ ((Content.List) peek ()).items.add (head);
+ })
+ })
+ .set_start (() => {
+ var siblings = ((BlockContent) peek ()).content;
+ if (siblings.size > 0 && siblings.last () is Content.List) {
+ push (siblings.last ());
+ } else {
+ Content.List list = _factory.create_list ();
+ list.bullet = Content.List.Bullet.ORDERED_NUMBER;
+ siblings.add (list);
+ push (list);
+ }
+ })
+ .set_reduce (() => {
+ (Content.List) pop ();
+ })
+ .set_name ("OrderedList");
+
+
+ Rule paragraph = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_PARAGRAPH,
+ Rule.option ({
+ Valadoc.TokenType.MARKDOWN_SPACE
+ }),
+ Rule.option ({
+ run
+ })
+ })
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => {
+ var head = (Paragraph) pop ();
+ ((BlockContent) peek ()).content.add (head);
+ })
+ .set_name ("Paragraph");
+
+
+ Rule block = Rule.seq ({
+ Valadoc.TokenType.MARKDOWN_BLOCK_START,
+ content,
+ Valadoc.TokenType.MARKDOWN_BLOCK_END
+ })
+ .set_start (() => { push (_factory.create_note ()); })
+ .set_reduce (() => {
+ var head = (Note) pop ();
+ ((BlockContent) peek ()).content.add (head);
+ })
+ .set_name ("Block");
+
+
+ Rule headline = Rule.seq ({
+ Rule.one_of ({
+ Valadoc.TokenType.MARKDOWN_HEADLINE_1.action ((token) => {
+ Headline h = (Headline) peek ();
+ h.level = 1;
+ }),
+ Valadoc.TokenType.MARKDOWN_HEADLINE_2.action ((token) => {
+ Headline h = (Headline) peek ();
+ h.level = 2;
+ })
+ }),
+ run,
+ Rule.option ({
+ Valadoc.TokenType.MARKDOWN_HEADLINE_HASH.action ((token) => {
+ id_registrar.register_symbol (token.value, element);
+ })
+ }),
+ Valadoc.TokenType.MARKDOWN_HEADLINE_END
+ })
+ .set_start (() => { push (_factory.create_headline ()); })
+ .set_reduce (() => {
+ Headline h = (Headline) pop ();
+ ((BlockContent) peek ()).content.add (h);
+ })
+ .set_name ("Headline");
+
+ content.set_rule (
+ Rule.many ({
+ Rule.one_of ({
+ paragraph,
+ unordered_list,
+ ordered_list,
+ headline,
+ block
+ })
+ })
+ );
+
+
+ Rule comment = Rule.seq ({
+ content,
+ Valadoc.TokenType.MARKDOWN_EOC
+ })
+ .set_start (() => { push (_factory.create_comment ()); })
+ .set_name ("Comment");
+
+ parser.set_root_rule (comment);
+ }
+
+ private Comment? _parse (Api.SourceComment comment) {
+ try {
+ _stack.clear ();
+ parser.parse (comment.content, comment.file.get_name (), comment.first_line, comment.first_column);
+ return (Comment) pop ();
+ } catch (ParserError e) {
+ return null;
+ }
+ }
+
+ private Taglet? _parse_block_taglet (Api.SourceComment comment, string taglet_name) {
+ Comment? cmnt = _parse (comment);
+ if (cmnt == null) {
+ return null;
+ }
+
+ Taglet? taglet = _factory.create_taglet (taglet_name);
+ BlockContent block = (BlockContent) taglet;
+ assert (taglet != null && block != null);
+
+ block.content.add_all (cmnt.content);
+
+ return taglet;
+ }
+
+ private Note? _parse_note (Api.SourceComment comment) {
+ Comment? cmnt = _parse (comment);
+ if (cmnt == null) {
+ return null;
+ }
+
+ Note note = _factory.create_note ();
+ note.content.add_all (cmnt.content);
+
+ return note;
+ }
+
+ private void add_taglet (ref Comment? comment, Taglet? taglet) {
+ if (taglet == null) {
+ return ;
+ }
+
+ if (comment == null) {
+ comment = _factory.create_comment ();
+ }
+
+ comment.taglets.add (taglet);
+ }
+
+ private void add_note (ref Comment? comment, Note? note) {
+ if (note == null) {
+ return ;
+ }
+
+ if (comment == null) {
+ comment = _factory.create_comment ();
+ }
+
+ if (comment.content.size == 0) {
+ comment.content.add (_factory.create_paragraph ());
+ }
+
+ comment.content.insert (1, note);
+ }
+
+ public Comment? parse (Api.Node element, Api.GirSourceComment gir_comment, GirMetaData metadata, Importer.InternalIdRegistrar id_registrar, string? this_name = null) {
+ this.metadata = metadata;
+ this.id_registrar = id_registrar;
+ this.gir_comment = gir_comment;
+ this.element = element;
+
+ // main:
+ Comment? cmnt = _parse (gir_comment);
+ if (cmnt != null) {
+ ImporterHelper.extract_short_desc (cmnt, _factory);
+ }
+
+
+ // deprecated:
+ if (gir_comment.deprecated_comment != null) {
+ Note? note = _parse_note (gir_comment.deprecated_comment);
+ add_note (ref cmnt, note);
+ }
+
+
+ // version:
+ if (gir_comment.version_comment != null) {
+ Note? note = _parse_note (gir_comment.version_comment);
+ add_note (ref cmnt, note);
+ }
+
+
+ // stability:
+ if (gir_comment.stability_comment != null) {
+ Note? note = _parse_note (gir_comment.stability_comment);
+ add_note (ref cmnt, note);
+ }
+
+
+ // return:
+ if (gir_comment.return_comment != null) {
+ Taglet? taglet = _parse_block_taglet (gir_comment.return_comment, "return");
+ add_taglet (ref cmnt, taglet);
+ }
+
+
+ // parameters:
++ Vala.MapIterator<string, Api.SourceComment> iter = gir_comment.parameter_iterator ();
+ for (bool has_next = iter.next (); has_next; has_next = iter.next ()) {
+ Taglets.Param? taglet = _parse_block_taglet (iter.get_value (), "param") as Taglets.Param;
+ string param_name = iter.get_key ();
+
+ taglet.is_c_self_param = (param_name == gir_comment.instance_param_name);
+ taglet.parameter_name = param_name;
+ add_taglet (ref cmnt, taglet);
+ }
+
+
+ this.metadata = null;
+ this.gir_comment = null;
+ this.id_registrar = null;
+ this.element = null;
+
+ return cmnt;
+ }
+
+
+ private void add_text (Valadoc.Token token) {
+ add_content_string (token.to_string ());
+ }
+
+ private void add_value (Valadoc.Token token) {
+ assert (token.value != null);
+
+ add_content_string (token.value);
+ }
+
+ private void add_content_string (string str) {
+ var text = peek () as Text;
+ if (text == null) {
+ push (text = _factory.create_text ());
+ }
+
+ text.content += str;
+ }
+
+ private void add_symbol_link (string symbol, bool accept_plural) {
+ var taglet = new Taglets.Link ();
+ taglet.c_accept_plural = accept_plural;
+ taglet.symbol_name = symbol;
+
+ var run = _factory.create_run (Run.Style.NONE);
+ run.content.add (taglet);
+
+ push (run);
+ }
+
+ private void preserve_token (Valadoc.Token token) {
+ assert (preserved_token == null);
+ preserved_token = token;
+ }
+
+ private string pop_preserved_link () {
+ assert (preserved_token != null);
+
+ Valadoc.Token _link_token = (owned) preserved_token;
+
+ // email:
+ if (_link_token.token_type == Valadoc.TokenType.MARKDOWN_MAIL) {
+ return "mailto:" + _link_token.value;
+ }
+
+ // http or https link:
+ if (_link_token.value != null) {
+ return _link_token.value;
+ }
+
+ // GTKDOC-ID:
+ return _link_token.word;
+ }
+
+ private string pop_preserved_path () {
+ assert (preserved_token != null);
+
+ Valadoc.Token _path_token = (owned) preserved_token;
+ return _path_token.word ?? _path_token.value;
+ }
+
+ private inline string run_to_string (Run run, string rule_name) throws Error {
+ StringBuilder builder = new StringBuilder ();
+ inline_to_string (run, rule_name, builder);
+ return (owned) builder.str;
+ }
+
+ private void inline_to_string (Inline element, string rule_name, StringBuilder? builder) throws Error {
+ if (element is Run) {
+ Run run = (Run) element;
+
+ foreach (Inline item in run.content) {
+ inline_to_string (item, rule_name, builder);
+ }
+ } else if (element is Text) {
+ Text text = (Text) element;
+ builder.append (text.content);
+ } else if (element is Embedded) {
+ throw new ContentToStringError.UNEXPECTED_ELEMENT ("Unexpected tag: <image> in `%s'", rule_name);
+ } else if (element is Link) {
+ throw new ContentToStringError.UNEXPECTED_ELEMENT ("Unexpected tag: <link> in `%s'", rule_name);
+ } else if (element is SourceCode) {
+ throw new ContentToStringError.UNEXPECTED_ELEMENT ("Unexpected tag: `|[' in `%s'", rule_name);
+ } else {
+ throw new ContentToStringError.UNEXPECTED_ELEMENT ("Unexpected tag in `%s''", rule_name);
+ }
+ }
+
+ private bool is_literal (string str) {
+ if (str == "TRUE") {
+ return true;
+ }
+
+ if (str == "FALSE") {
+ return true;
+ }
+
+ if (str == "NULL") {
+ return true;
+ }
+
+ if (str[0].isdigit ()) {
+ return true;
+ }
+
+ return true;
+ }
+
+ private bool is_error_parameter (string name) {
+ if (element == null || name != "error") {
+ return false;
+ }
+
+ if (!(element is Api.Method || element is Api.Delegate)) {
+ return false;
+ }
+
+ return element.get_children_by_types ({
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.CLASS}).size > 0;
+ }
+
+
+ public string resolve (string path) {
+ return path;
+ }
+
+ private void push (Object element) {
+ _stack.add (element);
+ }
+
+ private Object peek (int offset = -1) {
+ assert (_stack.size >= - offset);
+ return _stack.get (_stack.size + offset);
+ }
+
+ private Object pop () {
+ Object node = peek ();
+ _stack.remove_at (_stack.size - 1);
+ return node;
+ }
+
+ private inline string fix_resource_path (string path) {
+ return metadata.get_resource_path (path);
+ }
+ }
+
+
+ private errordomain Valadoc.Gtkdoc.ContentToStringError {
+ UNEXPECTED_ELEMENT
+ }
+
--- /dev/null
-using Gee;
-
-
+ /* gtkdocmarkdownscanner.vala
+ *
+ * Copyright (C) 2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Content;
+ using Valadoc;
- private LinkedList<State> states = new LinkedList<State> ();
+
+ public class Valadoc.Gtkdoc.MarkdownScanner : GLib.Object, Valadoc.Scanner {
+ private enum State {
+ NORMAL,
+ UNORDERED_LIST,
+ ORDERED_LIST,
+ BLOCK
+ }
+
+ private Settings _settings;
+ private Valadoc.Parser parser;
+
+ private unowned string _content;
+ private int _skip;
+
+ private StringBuilder _current_string = new StringBuilder ();
+ private unowned string _index;
+ private bool contains_at;
+
+ private int _line;
+ private int _column;
+ private int _last_line;
+ private int _last_column;
+ private bool _stop;
+
+ private string? headline_end;
+
+ private Regex regex_mail;
+
- states.offer_head (state);
++ private Vala.List<State> states = new Vala.ArrayList<State> ();
+
+ private inline void push_state (State state) {
- return states.poll_head ();
++ states.insert (0, state);
+ }
+
+ private inline State pop_state () {
- return states.peek_head ();
++ return states.remove_at (0);
+ }
+
+ private inline State peek_state () {
- if (states.peek () == State.UNORDERED_LIST) {
++ return states.get (0);
+ }
+
+
+ public MarkdownScanner (Settings settings) {
+ _settings = settings;
+
+ try {
+ regex_mail = new Regex ("^[A-Za-z0-9._-]+@[A-Za-z0-9._-]+$");
+ } catch (Error e) {
+ assert_not_reached ();
+ }
+ }
+
+ public void set_parser (Valadoc.Parser parser) {
+ this.parser = parser;
+ }
+
+ public void reset () {
+ _stop = false;
+ _last_line = 0;
+ _last_column = 0;
+ _line = 0;
+ _column = 0;
+ _skip = 0;
+ _current_string.erase (0, -1);
+ contains_at = false;
+
+ states.clear ();
+ push_state (State.NORMAL);
+ }
+
+ public void scan (string content) throws ParserError {
+ _content = content;
+ _index = _content;
+
+
+ // Accept block taglets:
+ if (handle_newline (_index, true)) {
+ _index = _index.next_char ();
+ } else {
+ // Empty string
+ emit_token (Valadoc.TokenType.MARKDOWN_PARAGRAPH);
+ }
+
+
+ while (!_stop && _index.get_char () != 0) {
+ unichar c = _index.get_char ();
+ accept (c);
+
+ _index = _index.next_char ();
+ }
+
+
+ // Close open blocks:
+ while (peek_state () != State.NORMAL) {
+ if (peek_state () == State.BLOCK) {
+ emit_token (Valadoc.TokenType.MARKDOWN_BLOCK_END);
+ pop_state ();
+ } else {
+ close_block ();
+ }
+ }
+
+
+ emit_token (Valadoc.TokenType.MARKDOWN_EOC);
+ }
+
+ private void accept (unichar c) throws ParserError {
+ _column++;
+ if (_skip > 0) {
+ _skip--;
+ return ;
+ }
+
+ // In headline:
+ string? hash = null;
+
+ if (headline_end != null && is_headline_end (ref _index, headline_end, out hash)) {
+ if (hash != null) {
+ emit_token (Valadoc.TokenType.MARKDOWN_HEADLINE_HASH, hash);
+ }
+ emit_token (Valadoc.TokenType.MARKDOWN_HEADLINE_END);
+ headline_end = null;
+
+ handle_newline (_index, true);
+
+ return ;
+ }
+
+ switch (c) {
+ case '\\':
+ switch (get_next_char ()) {
+ case '(':
+ if (get_next_char (2) == ')') {
+ _current_string.append ("()");
+ _skip += 2;
+ break;
+ }
+
+ _current_string.append ("\\(");
+ _skip++;
+ break;
+
+ case '<':
+ append_char ('<');
+ _skip++;
+ break;
+
+ case '>':
+ append_char ('>');
+ _skip++;
+ break;
+
+ case '@':
+ append_char ('@');
+ _skip++;
+ break;
+
+ case '%':
+ append_char ('%');
+ _skip++;
+ break;
+
+ case '#':
+ append_char ('#');
+ _skip++;
+ break;
+
+ default:
+ append_char ('\\');
+ break;
+ }
+
+ break;
+
+ case ':':
+ unichar next_char = get_next_char ();
+ unichar next2_char = get_next_char (2);
+
+ // :id or ::id
+ if ((_current_string.len == 0 || !_current_string.str[_current_string.len - 1].isalpha ())
+ && (next_char.isalpha () || (next_char == ':' && next2_char.isalpha ()))) {
+
+ unowned string _iter;
+ if (next_char == ':') {
+ _iter = _index.offset (2);
+ _skip++;
+ } else {
+ _iter = _index.offset (1);
+ }
+
+ while (_iter[0].isalnum () || _iter[0] == '_' || (_iter[0] == '-' && _iter[1].isalnum ())) {
+ _iter = _iter.offset (1);
+ _skip++;
+ }
+
+ emit_token (Valadoc.TokenType.MARKDOWN_LOCAL_GMEMBER, _index.substring (0, _skip + 1));
+ break;
+ }
+
+ append_char (c);
+ break;
+
+ case '%':
+ // " %foo", "-%foo" but not " %", "a%foo", ...
+ if ((_current_string.len == 0 || !_current_string.str[_current_string.len - 1].isalpha ()) && get_next_char ().isalpha ()) {
+ unowned string _iter = _index.offset (1);
+
+ while (_iter[0].isalnum () || _iter[0] == '_') {
+ _iter = _iter.offset (1);
+ _skip++;
+ }
+
+ emit_token (Valadoc.TokenType.MARKDOWN_CONSTANT, _index.substring (1, _skip));
+ break;
+ }
+ // %numeric:
+ if ((_current_string.len == 0 || !_current_string.str[_current_string.len - 1].isalpha ()) && get_next_char ().isdigit ()) {
+ unowned string _iter = _index.offset (1);
+
+ while (_iter[0].isdigit ()) {
+ _iter = _iter.offset (1);
+ _skip++;
+ }
+
+ // Integers:
+ if (_iter[0].tolower () == 'u' && _iter[0].tolower () == 'l') {
+ _iter = _iter.offset (1);
+ _skip += 2;
+
+ emit_token (Valadoc.TokenType.MARKDOWN_CONSTANT, _index.substring (1, _skip));
+ break;
+ } else if (_iter[0].tolower () == 'u' || _iter[0].tolower () == 'l') {
+ _iter = _iter.offset (1);
+ _skip++;
+
+ emit_token (Valadoc.TokenType.MARKDOWN_CONSTANT, _index.substring (1, _skip));
+ break;
+ }
+
+
+ // Float, double:
+ if (_iter[0] == '.' && _iter[1].isdigit ()) {
+ _iter = _iter.offset (2);
+ _skip += 2;
+ }
+
+ while (_iter[0].isdigit ()) {
+ _iter = _iter.offset (1);
+ _skip++;
+ }
+
+ if (_iter[0].tolower () == 'f' || _iter[0].tolower () == 'l') {
+ _iter = _iter.offset (1);
+ _skip++;
+ }
+
+ emit_token (Valadoc.TokenType.MARKDOWN_CONSTANT, _index.substring (1, _skip));
+ break;
+ }
+
+ append_char (c);
+ break;
+
+ case '#':
+ // " #foo", "-#foo" but not " #"", "a#""foo", ...
+ if ((_current_string.len == 0 || !_current_string.str[_current_string.len - 1].isalpha ()) && get_next_char ().isalpha ()) {
+ unowned string _iter = _index.offset (1);
+
+ while (_iter[0].isalnum () || _iter[0] == '_') {
+ _iter = _iter.offset (1);
+ _skip++;
+ }
+
+ // signals, fields, properties
+ bool is_field = false;
+ if (((_iter[0] == ':' || _iter[0] == '.') && _iter[1].isalpha ())
+ || (_iter.has_prefix ("::") && _iter[2].isalpha ())) {
+
+ is_field = (_iter[0] == '.');
+ _iter = _iter.offset (2);
+ _skip += 2;
+
+ while (_iter[0].isalnum () || _iter[0] == '_' || (!is_field && _iter[0] == '-')) {
+ _iter = _iter.offset (1);
+ _skip++;
+ }
+ }
+
+ if (is_field && _iter.has_prefix ("()")) {
+ _skip += 2;
+
+ emit_token (Valadoc.TokenType.MARKDOWN_SYMBOL, _index.substring (1, _skip - 2));
+ } else {
+ emit_token (Valadoc.TokenType.MARKDOWN_SYMBOL, _index.substring (1, _skip));
+ }
+
+ break;
+ }
+
+ append_char (c);
+ break;
+
+ case '@':
+ // " @foo", "-@foo" but not " @", "a@foo", ...
+ if ((_current_string.len == 0 || !_current_string.str[_current_string.len - 1].isalpha ())) {
+ if (get_next_char ().isalpha ()) {
+ unowned string _iter = _index.offset (1);
+
+ while (_iter[0].isalnum () || _iter[0] == '_') {
+ _iter = _iter.offset (1);
+ _skip++;
+ }
+
+ emit_token (Valadoc.TokenType.MARKDOWN_PARAMETER, _index.substring (1, _skip));
+ break;
+ } else if (_index.has_prefix ("@...")) {
+ _skip += 3;
+ emit_token (Valadoc.TokenType.MARKDOWN_PARAMETER, "...");
+ break;
+ }
+ }
+
+ append_char (c);
+ contains_at = true;
+ break;
+
+ case '(':
+ if (get_next_char () == ')' && is_id ()) {
+ string id = _current_string.str;
+ _current_string.erase (0, -1);
+ contains_at = false;
+
+ emit_token (Valadoc.TokenType.MARKDOWN_FUNCTION, id);
+ _skip++;
+ break;
+ }
+
+ emit_token (Valadoc.TokenType.MARKDOWN_OPEN_PARENS);
+ break;
+
+ case ')':
+ emit_token (Valadoc.TokenType.MARKDOWN_CLOSE_PARENS);
+ break;
+
+ case '[':
+ unowned string iter = _index;
+ int count = 1;
+ while (iter[0] != '\n' && iter[0] != '\0' && count > 0) {
+ iter = iter.offset (1);
+ switch (iter[0]) {
+ case '[':
+ count++;
+ break;
+
+ case ']':
+ count--;
+ break;
+ }
+ }
+
+ if (iter[0] == ']') {
+ emit_token (Valadoc.TokenType.MARKDOWN_OPEN_BRACKET);
+ } else {
+ append_char ('[');
+ }
+ break;
+
+ case ']':
+ emit_token (Valadoc.TokenType.MARKDOWN_CLOSE_BRACKET);
+ break;
+
+ case '<':
+ emit_token (Valadoc.TokenType.MARKDOWN_LESS_THAN);
+ break;
+
+ case '>':
+ emit_token (Valadoc.TokenType.MARKDOWN_GREATER_THAN);
+ break;
+
+ case '!':
+ emit_token (Valadoc.TokenType.MARKDOWN_EXCLAMATION_MARK);
+ break;
+
+ case '|':
+ if (get_next_char () == '[') {
+ unowned string _iter = _index.offset (2);
+ int end = _iter.index_of ("]|");
+ if (end < 0) {
+ append_char ('|');
+ } else {
+ emit_token (Valadoc.TokenType.MARKDOWN_SOURCE, _index.substring (2, end));
+ _skip = end + 3;
+ }
+
+ break;
+ }
+
+ append_char (c);
+ break;
+
+ case '\t':
+ case ' ':
+ unowned string _iter = _index.offset (1);
+ _skip += skip_spaces (ref _iter);
+
+ if (_iter[0] != '\n' && _iter[0] != '\0') {
+ emit_token (Valadoc.TokenType.MARKDOWN_SPACE);
+ }
+ break;
+
+ case '\r':
+ // Ignore
+ break;
+
+ case '\n':
+ unowned string _iter = _index.offset (1);
+
+ _line++;
+ _column = 0;
+ _last_column = 0;
+ handle_newline (_iter, false);
+ break;
+
+ default:
+ append_char (c);
+ break;
+ }
+ }
+
+ private bool handle_newline (string _iter, bool is_paragraph) throws ParserError {
+ int leading_spaces;
+
+ leading_spaces = skip_spaces (ref _iter);
+
+ if (_iter[0] == '\0') {
+ return false;
+ }
+
+ // Do not emit paragraphs twice:
+ if (is_paragraph) {
+ while (_iter[0] == '\n') {
+ _line++;
+ _iter = _iter.offset (1);
+ leading_spaces = skip_spaces (ref _iter);
+ }
+ }
+
+ bool in_block = states.contains (State.BLOCK);
+ if (_iter[0] == '>') {
+ if (!in_block) {
+ close_block ();
+
+ if (is_paragraph) {
+ _column += (int) ((char*) _iter - (char*) _index);
+ _index = _iter.offset (1);
+ emit_token (Valadoc.TokenType.MARKDOWN_BLOCK_START);
+ push_state (State.BLOCK);
+ }
+ }
+
+ if (in_block || is_paragraph) {
+ _column++;
+ _index = _iter;
+
+ _iter = _iter.offset (1);
+ skip_spaces (ref _iter);
+ }
+ } else if (in_block && is_paragraph) {
+ _column += (int) ((char*) _iter - (char*) _index);
+ _index = _iter;
+
+ close_block ();
+
+ emit_token (Valadoc.TokenType.MARKDOWN_BLOCK_END);
+ pop_state ();
+ }
+
+
+ int list_token_len = 0;
+ bool is_unsorted_list = _iter[0] == '-' && _iter[1].isspace ();
+ bool is_sorted_list = is_ordered_list (_iter, out list_token_len);
+ if ((is_unsorted_list || is_sorted_list) && (is_paragraph || states.contains (State.UNORDERED_LIST) || states.contains (State.ORDERED_LIST))) {
+ Valadoc.TokenType start_token = Valadoc.TokenType.MARKDOWN_ORDERED_LIST_ITEM_START;
+ State new_state = State.ORDERED_LIST;
+
+ if (is_unsorted_list) {
+ start_token = Valadoc.TokenType.MARKDOWN_UNORDERED_LIST_ITEM_START;
+ new_state = State.UNORDERED_LIST;
+ list_token_len = 2;
+ }
+
+
+ _iter = _iter.offset (list_token_len);
+ close_block ();
+
+ skip_spaces (ref _iter);
+
+ _column += (int) ((char*) _iter - (char*) _index);
+ _index = _iter.offset (-1);
+ emit_token (start_token);
+ push_state (new_state);
+
+ emit_token (Valadoc.TokenType.MARKDOWN_PARAGRAPH);
+ return true;
+ }
+
+ if ((_iter[0] == '#' && _iter[1].isspace ()) || (_iter[0] == '#' && _iter[1] == '#' && _iter[2].isspace ()) && is_paragraph) {
+ close_block ();
+
+ if (_iter[1] != '#') {
+ _iter = _iter.offset (1);
+ emit_token (Valadoc.TokenType.MARKDOWN_HEADLINE_1);
+ headline_end = "#";
+ } else {
+ emit_token (Valadoc.TokenType.MARKDOWN_HEADLINE_2);
+ _iter = _iter.offset (2);
+ headline_end = "##";
+ }
+
+ _column += (int) ((char*) _iter - (char*) _index);
+ _index = _iter.offset (-1);
+
+ return true;
+ }
+
+ if (is_paragraph) {
+ if (leading_spaces == 0) {
+ close_block ();
+ }
+
+ _column += (int) ((char*) _iter - (char*) _index);
+ _index = _iter.offset (-1);
+ emit_token (Valadoc.TokenType.MARKDOWN_PARAGRAPH);
+ } else if (_iter[0] == '\n') {
+ _line++;
+ _column = 0;
+ _last_column = 0;
+
+ handle_newline (_iter.offset (1), true);
+ } else {
+ emit_token (Valadoc.TokenType.MARKDOWN_SPACE);
+ }
+
+ return true;
+ }
+
+ private bool is_headline_end (ref unowned string iter, string separator, out string? hash) {
+ unowned string _iter = iter;
+ hash = null;
+
+
+ if (_iter[0] == '\n' || _iter[0] == '\0') {
+ _line++;
+ return true;
+ }
+ if (!_iter.has_prefix (separator)) {
+ return false;
+ }
+
+ _iter = _iter.offset (separator.length);
+
+
+ skip_spaces (ref _iter);
+ if (_iter[0] == '\n' || _iter[0] == '\0') {
+ iter = _iter;
+ _line++;
+ return true;
+ } else if (!_iter.has_prefix ("{#")) {
+ return false;
+ }
+ _iter = _iter.offset (2);
+
+ unowned string id_start = _iter;
+ int hash_len = 0;
+
+ while (_iter[0] != '}' && _iter[0] != '\n' && _iter[0] != '\0') {
+ _iter = _iter.offset (1);
+ hash_len++;
+ }
+
+ if (_iter[0] != '}') {
+ return false;
+ }
+
+ _iter = _iter.offset (1);
+
+ skip_spaces (ref _iter);
+
+ if (_iter[0] == '\n' || _iter[0] == '\0') {
+ hash = id_start.substring (0, hash_len);
+ iter = _iter;
+ _line++;
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool is_ordered_list (string iter, out int numeric_prefix_count) {
+ numeric_prefix_count = 0;
+ while (iter[0] >= '0' && iter[0] <= '9') {
+ numeric_prefix_count++;
+ iter = iter.offset (1);
+ }
+
+ if (numeric_prefix_count > 0 && iter[0] == '.' && iter[1].isspace ()) {
+ numeric_prefix_count++;
+ return true;
+ }
+
+ return false;
+ }
+
+ private inline int skip_spaces (ref unowned string _iter) {
+ int count = 0;
+ while (_iter[0] == ' ' || _iter[0] == '\t' || _iter[0] == '\r') {
+ _iter = _iter.offset (1);
+ count++;
+ }
+
+ return count;
+ }
+
+ private bool close_block () throws ParserError {
- } else if (states.peek () == State.ORDERED_LIST) {
++ if (states.get (0) == State.UNORDERED_LIST) {
+ emit_token (Valadoc.TokenType.MARKDOWN_UNORDERED_LIST_ITEM_END);
+ pop_state ();
+ return true;
++ } else if (states.get (0) == State.ORDERED_LIST) {
+ emit_token (Valadoc.TokenType.MARKDOWN_ORDERED_LIST_ITEM_END);
+ pop_state ();
+ return true;
+ }
+
+ return false;
+ }
+
+ public void end () throws ParserError {
+ emit_token (Valadoc.TokenType.EOF);
+ }
+
+ public void stop () {
+ _stop = true;
+ }
+
+ public string get_line_content () {
+ StringBuilder builder = new StringBuilder ();
+ weak string line_start = _index;
+ unichar c;
+
+ while ((char*) line_start > (char*) _content && line_start.prev_char ().get_char () != '\n') {
+ line_start = line_start.prev_char ();
+ }
+
+ while ((c = line_start.get_char ()) != '\n' && c != '\0') {
+ if (c == '\t') {
+ builder.append_c (' ');
+ } else {
+ builder.append_unichar (c);
+ }
+ line_start = line_start.next_char ();
+ }
+
+ return builder.str;
+ }
+
+ private void emit_token (Valadoc.TokenType type, string? value = null) throws ParserError {
+ emit_current_word ();
+
+ parser.accept_token (new Valadoc.Token.from_type (type, get_begin (), get_end (_skip), value));
+ }
+
+ private void emit_current_word () throws ParserError {
+ if (_current_string.len > 0) {
+ if (is_mail ()) {
+ parser.accept_token (new Valadoc.Token.from_type (Valadoc.TokenType.MARKDOWN_MAIL, get_begin (), get_end (_skip), _current_string.str));
+ } else if (_current_string.str.has_prefix ("http://") || _current_string.str.has_prefix ("https://")) {
+ // TODO: (https?:[\/]{2}[^\s]+?)
+ parser.accept_token (new Valadoc.Token.from_type (Valadoc.TokenType.MARKDOWN_LINK, get_begin (), get_end (_skip), _current_string.str));
+ } else {
+ parser.accept_token (new Valadoc.Token.from_word (_current_string.str, get_begin (), get_end (-1)));
+ }
+
+ _current_string.erase (0, -1);
+ contains_at = false;
+ }
+ }
+
+ private SourceLocation get_begin () {
+ return SourceLocation (_last_line, get_line_start_column () + _last_column);
+ }
+
+ private SourceLocation get_end (int offset = 0) {
+ return SourceLocation (_line, get_line_start_column () + _column + offset);
+ }
+
+ public int get_line_start_column () {
+ return 0;
+ }
+
+ private void append_char (unichar c) {
+ _current_string.append_unichar (c);
+ }
+
+ private unichar get_next_char (int offset = 1) {
+ return _index.get_char (_index.index_of_nth_char (offset));
+ }
+
+ private inline bool is_mail () {
+ return contains_at && regex_mail.match (_current_string.str);
+ }
+
+ private bool is_id () {
+ if (_current_string.len == 0) {
+ return false;
+ }
+
+ if (_current_string.str[0].isalpha () == false && _current_string.str[0] != '_') {
+ return false;
+ }
+
+ for (int i = 1; i < _current_string.len ; i++) {
+ if (_current_string.str[i].isalnum () == false && _current_string.str[i] != '_') {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
--- /dev/null
-using Gee;
-
+ /* importhelper.vala
+ *
+ * Copyright (C) 2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Content;
- Iterator<Inline> iter = run.content.iterator ();
+
+ namespace Valadoc.ImporterHelper {
+
+ //
+ // resolve-parameter-ctype:
+ //
+
+ internal string? resolve_parameter_ctype (Api.Tree tree, Api.Node element, string parameter_name,
+ out string? param_name, out string? param_array_name, out bool is_return_type_len)
+ {
+ string[]? parts = split_type_name (parameter_name);
+ is_return_type_len = false;
+ param_array_name = null;
+
+ Api.FormalParameter? param = null; // type parameter or formal parameter
+ foreach (Api.Node node in element.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false)) {
+ if (node.name == parts[0]) {
+ param = node as Api.FormalParameter;
+ break;
+ }
+
+ if (((Api.FormalParameter) node).implicit_array_length_cparameter_name == parts[0]) {
+ param_array_name = ((Api.FormalParameter) node).name;
+ break;
+ }
+ }
+
+ if (element is Api.Callable
+ && ((Api.Callable) element).implicit_array_length_cparameter_name == parts[0])
+ {
+ is_return_type_len = true;
+ }
+
+ if (parts.length == 1) {
+ param_name = parameter_name;
+ return null;
+ }
+
+
+ Api.Item? inner = null;
+
+ if (param_array_name != null || is_return_type_len) {
+ inner = tree.search_symbol_str (null, "int");
+ } else if (param != null) {
+ inner = param.parameter_type;
+ }
+
+ while (inner != null) {
+ if (inner is Api.TypeReference) {
+ inner = ((Api.TypeReference) inner).data_type;
+ } else if (inner is Api.Pointer) {
+ inner = ((Api.Pointer) inner).data_type;
+ } else if (inner is Api.Array) {
+ inner = ((Api.Array) inner).data_type;
+ } else {
+ break ;
+ }
+ }
+
+
+ if (inner == null) {
+ param_name = parameter_name;
+ return null;
+ }
+
+ string? cname = null;
+ if (inner is Api.ErrorDomain) {
+ cname = ((Api.ErrorDomain) inner).get_cname ();
+ } else if (inner is Api.Struct) {
+ cname = ((Api.Struct) inner).get_cname ();
+ } else if (inner is Api.Class) {
+ cname = ((Api.Class) inner).get_cname ();
+ } else if (inner is Api.Enum) {
+ cname = ((Api.Enum) inner).get_cname ();
+ } else {
+ assert_not_reached ();
+ }
+
+ param_name = (owned) parts[0];
+ return "c::" + cname + parts[1] + parts[2];
+ }
+
+
+ private string[]? split_type_name (string id) {
+ unichar c;
+
+ for (unowned string pos = id; (c = pos.get_char ()) != '\0'; pos = pos.next_char ()) {
+ switch (c) {
+ case '-': // ->
+ return {id.substring (0, (long) (((char*) pos) - ((char*) id))), "->", (string) (((char*) pos) + 2)};
+
+ case ':': // : or ::
+ string sep = (pos.next_char ().get_char () == ':')? "::" : ":";
+ return {id.substring (0, (long) (((char*) pos) - ((char*) id))), sep, (string) (((char*) pos) + sep.length)};
+
+ case '.':
+ return {id.substring (0, (long) (((char*) pos) - ((char*) id))), ".", (string) (((char*) pos) + 1)};
+ }
+ }
+
+ return {id};
+ }
+
+
+
+ //
+ // extract-short-desc:
+ //
+
+ internal void extract_short_desc (Comment comment, ContentFactory factory) {
+ if (comment.content.size == 0) {
+ return ;
+ }
+
+ Paragraph? first_paragraph = comment.content[0] as Paragraph;
+ if (first_paragraph == null) {
+ // add empty paragraph to avoid non-text as short descriptions
+ comment.content.insert (1, factory.create_paragraph ());
+ return ;
+ }
+
+
+ // avoid fancy stuff in short descriptions:
+ first_paragraph.horizontal_align = null;
+ first_paragraph.vertical_align = null;
+ first_paragraph.style = null;
+
+
+ Paragraph? second_paragraph = split_paragraph (first_paragraph, factory);
+ if (second_paragraph == null) {
+ return ;
+ }
+
+ if (second_paragraph.is_empty () == false) {
+ comment.content.insert (1, second_paragraph);
+ }
+ }
+
+ private inline Text? split_text (Text text, ContentFactory factory) {
+ int offset = 0;
+ while ((offset = text.content.index_of_char ('.', offset)) >= 0) {
+ if (offset >= 2) {
+ // ignore "e.g."
+ unowned string cmp4 = ((string) (((char*) text.content) + offset - 2));
+ if (cmp4.has_prefix (" e.g.") || cmp4.has_prefix ("(e.g.")) {
+ offset = offset + 3;
+ continue;
+ }
+
+ // ignore "i.e."
+ if (cmp4.has_prefix (" i.e.") || cmp4.has_prefix ("(i.e.")) {
+ offset = offset + 3;
+ continue;
+ }
+ }
+
+ unowned string cmp0 = ((string) (((char*) text.content) + offset));
+
+ // ignore ... (varargs)
+ if (cmp0.has_prefix ("...")) {
+ offset = offset + 3;
+ continue;
+ }
+
+ // ignore numbers
+ if (cmp0.get (1).isdigit ()) {
+ offset = offset + 2;
+ continue;
+ }
+
+
+ Text sec = factory.create_text (text.content.substring (offset+1, -1));
+ text.content = text.content.substring (0, offset+1);
+ return sec;
+ }
+
+ return null;
+ }
+
+ private inline Run? split_run (Run run, ContentFactory factory) {
+ if (run.style != Run.Style.NONE) {
+ return null;
+ }
+
+ Run? sec = null;
+
+
- Iterator<Inline> iter = p.content.iterator ();
++ Vala.Iterator<Inline> iter = run.content.iterator ();
+ for (bool has_next = iter.next (); has_next; has_next = iter.next ()) {
+ Inline item = iter.get ();
+ if (sec == null) {
+ Inline? tmp = split_inline (item, factory);
+ if (tmp != null) {
+ sec = factory.create_run (run.style);
+ sec.content.add (tmp);
+ }
+ } else {
+ sec.content.add (item);
+ iter.remove ();
+ }
+ }
+
+ return sec;
+ }
+
+ private inline Inline? split_inline (Inline item, ContentFactory factory) {
+ if (item is Text) {
+ return split_text ((Text) item, factory);
+ } else if (item is Run) {
+ return split_run ((Run) item, factory);
+ }
+
+ return null;
+ }
+
+ private inline Paragraph? split_paragraph (Paragraph p, ContentFactory factory) {
+ Paragraph? sec = null;
+
++ Vala.Iterator<Inline> iter = p.content.iterator ();
+ for (bool has_next = iter.next (); has_next; has_next = iter.next ()) {
+ Inline item = iter.get ();
+ if (sec == null) {
+ Inline? tmp = split_inline (item, factory);
+ if (tmp != null) {
+ sec = factory.create_paragraph ();
+ sec.horizontal_align = p.horizontal_align;
+ sec.vertical_align = p.vertical_align;
+ sec.style = p.style;
+ sec.content.add (tmp);
+ }
+ } else {
+ sec.content.add (item);
+ iter.remove ();
+ }
+ }
+
+ return sec;
+ }
+
+ }
--- /dev/null
-using Gee;
-
+ /* wiki.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private ArrayList<WikiPage> wikipages;
+
+ public class Valadoc.WikiPage : Object, Documentation {
+ public Content.Page documentation {
+ protected set;
+ get;
+ }
+
+ public string documentation_str {
+ private set;
+ get;
+ }
+
+ public string path {
+ private set;
+ get;
+ }
+
+ public string name {
+ private set;
+ get;
+ }
+
+
+ public Api.Package? package {
+ get {
+ return _package;
+ }
+ }
+
+ private Api.Package _package;
+
+ /**
+ * The corresponding file name
+ */
+ public string? get_filename () {
+ return Path.get_basename(this.path);
+ }
+
+ public WikiPage (string name, string path, Api.Package package) {
+ this._package = package;
+ this.name = name;
+ this.path = path;
+ }
+
+ public void read (ErrorReporter reporter) {
+ try {
+ string content;
+ FileUtils.get_contents (this.path, out content);
+ this.documentation_str = content;
+ } catch (FileError err) {
+ reporter.simple_error (null, "Unable to read file '%s': %s", this.path, err.message);
+ }
+ }
+
+ public void parse (DocumentationParser docparser, Api.Package pkg) {
+ documentation = docparser.parse_wikipage (pkg, this);
+ }
+ }
+
+
+ public class Valadoc.WikiPageTree : Object {
- public Collection<WikiPage> get_pages () {
- return this.wikipages == null? Collection.empty<WikiPage> () : this.wikipages.read_only_view;
++ private Vala.ArrayList<WikiPage> wikipages;
+
+
+ public WikiPageTree () {
+ }
+
- this.wikipages = new ArrayList<WikiPage> ();
++ public Vala.Collection<WikiPage> get_pages () {
++ return this.wikipages == null ? new Vala.ArrayList<WikiPage> () : this.wikipages;
+ }
+
+ public WikiPage? search (string name) {
+ if (this.wikipages == null) {
+ return null;
+ }
+
+ foreach (WikiPage page in this.wikipages ) {
+ if (page.name == name) {
+ return page;
+ }
+ }
+ return null;
+ }
+
+ private void create_tree_from_path (DocumentationParser docparser, Api.Package package,
+ ErrorReporter reporter, string path, string? nameoffset = null)
+ {
+ try {
+ Dir dir = Dir.open (path);
+
+ for (string? curname = dir.read_name (); curname!=null ; curname = dir.read_name ()) {
+ string filename = Path.build_filename (path, curname);
+ if (curname.has_suffix (".valadoc") && FileUtils.test (filename, FileTest.IS_REGULAR)) {
+ WikiPage wikipage = new WikiPage ((nameoffset!=null)
+ ? Path.build_filename (nameoffset, curname)
+ : curname, filename, package);
+ this.wikipages.add(wikipage);
+ wikipage.read (reporter);
+ } else if (FileUtils.test (filename, FileTest.IS_DIR)) {
+ this.create_tree_from_path (docparser, package, reporter, filename, (nameoffset!=null)
+ ? Path.build_filename (nameoffset, curname)
+ : curname);
+ }
+ }
+ } catch (FileError err) {
+ reporter.simple_error (null, "Unable to open directory '%s': %s", path, err.message);
+ }
+ }
+
+ public void parse (Settings settings, DocumentationParser docparser, Api.Package package, ErrorReporter reporter) {
+ weak string path = settings.wiki_directory;
+ if (path == null) {
+ return ;
+ }
+
++ this.wikipages = new Vala.ArrayList<WikiPage> ();
+ this.create_tree_from_path (docparser, package, reporter, path);
+
+ foreach (WikiPage page in this.wikipages) {
+ page.parse (docparser, package);
+ }
+ }
+
+ public void check (Settings settings, DocumentationParser docparser, Api.Package pkg) {
+ if (this.wikipages == null) {
+ return ;
+ }
+
+ foreach (WikiPage page in this.wikipages) {
+ docparser.check_wikipage (pkg, page);
+ }
+ }
+ }
+
+
--- /dev/null
+ /* wikiscanner.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
++
+ public class Valadoc.WikiScanner : Object, Scanner {
+
+ public WikiScanner (Settings settings) {
+ _settings = settings;
+ }
+
+ private Settings _settings;
+ private Parser _parser;
+
+ private string _content;
+ private unowned string _index;
+ private bool _stop;
+ private int _last_line;
+ private int _last_column;
+ private int _line;
+ private int _column;
+ private bool _url_escape_mode;
+ private bool _code_escape_mode;
+ private unichar _last_char;
+ private int _skip;
+ private StringBuilder _current_string = new StringBuilder ();
+
+ public void set_parser (Parser parser) {
+ _parser = parser;
+ }
+
+ public virtual void reset () {
+ _stop = false;
+ _last_line = 0;
+ _last_column = 0;
+ _line = 0;
+ _column = 0;
+ _url_escape_mode = false;
+ _code_escape_mode = false;
+ _last_char = 0;
+ _skip = 0;
+ _current_string.erase (0, -1);
+ }
+
+ public void scan (string content) throws ParserError {
+ this._content = content;
+
+ for (_index = _content; !_stop && _index.get_char () != 0; _index = _index.next_char ()) {
+ unichar c = _index.get_char ();
+ accept (c);
+ }
+ }
+
+ public void end () throws ParserError {
+ emit_token (TokenType.EOF);
+ }
+
+ public virtual void stop () {
+ _stop = true;
+ }
+
+ public void set_url_escape_mode (bool escape_mode) {
+ _url_escape_mode = escape_mode;
+ }
+
+ public void set_code_escape_mode (bool escape_mode) {
+ _code_escape_mode = escape_mode;
+ }
+
+ public int get_line () {
+ return _line;
+ }
+
+ public virtual string get_line_content () {
+ StringBuilder builder = new StringBuilder ();
+ weak string line_start = _index;
+ unichar c;
+
+ while ((char*) line_start > (char*) _content && line_start.prev_char ().get_char () != '\n') {
+ line_start = line_start.prev_char ();
+ }
+
+ while ((c = line_start.get_char ()) != '\n' && c != '\0') {
+ if (c == '\t') {
+ builder.append_c (' ');
+ } else {
+ builder.append_unichar (c);
+ }
+ line_start = line_start.next_char ();
+ }
+
+ return builder.str;
+ }
+
+ protected unichar get_next_char (int offset = 1) {
+ return _index.get_char (_index.index_of_nth_char (offset));
+ }
+
+ protected virtual void accept (unichar c) throws ParserError {
+ _column++;
+ if (_skip == 0) {
+ if (_code_escape_mode) {
+ if (c == '}' && get_next_char (1) == '}' && get_next_char (2) == '}') {
+ _code_escape_mode = false; // This is a temporary hack
+ emit_token (TokenType.TRIPLE_CLOSED_BRACE);
+ _skip = 2;
+ } else {
+ append_char (c);
+ }
+ return;
+ } else if (_url_escape_mode) {
+ switch (c) {
+ // Reserved characters
+ case ';':
+ case '/':
+ case '?':
+ case ':':
+ case '@':
+ case '#':
+ case '=':
+ case '&':
+ // Special characters
+ case '$':
+ case '-':
+ case '_':
+ case '.':
+ case '+':
+ case '!':
+ case '*':
+ case '\'':
+ case '(':
+ case ')':
+ case ',':
+ append_char (c);
+ return;
+ default:
+ break;
+ }
+ }
+
+ switch (c) {
+ case '@':
+ emit_token (TokenType.AROBASE);
+ break;
+
+ case '{':
+ look_for_three (c,
+ TokenType.OPEN_BRACE,
+ TokenType.DOUBLE_OPEN_BRACE,
+ TokenType.TRIPLE_OPEN_BRACE);
+ break;
+
+ case '}':
+ look_for_three (c,
+ TokenType.CLOSED_BRACE,
+ TokenType.DOUBLE_CLOSED_BRACE,
+ TokenType.TRIPLE_CLOSED_BRACE);
+ break;
+
+ case '[':
+ look_for_two_or_append (c, TokenType.DOUBLE_OPEN_BRACKET);
+ break;
+
+ case ']':
+ look_for_two_or_append (c, TokenType.DOUBLE_CLOSED_BRACKET);
+ break;
+
+ case '|':
+ look_for_two (c,
+ TokenType.PIPE,
+ TokenType.DOUBLE_PIPE);
+ break;
+
+ case ')':
+ if (get_next_char () == ')') {
+ emit_token (TokenType.ALIGN_RIGHT);
+ _skip = 1;
+ } else if (get_next_char () == '(') {
+ emit_token (TokenType.ALIGN_CENTER);
+ _skip = 1;
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '-':
+ emit_token (TokenType.MINUS);
+ break;
+
+ case '=':
+ look_for_five (c,
+ TokenType.EQUAL_1,
+ TokenType.EQUAL_2,
+ TokenType.EQUAL_3,
+ TokenType.EQUAL_4,
+ TokenType.EQUAL_5);
+ break;
+
+ case '<':
+ if (!look_for ("<<BR>>", TokenType.BREAK)) {
+ emit_token (TokenType.LESS_THAN);
+ }
+ break;
+
+ case '>':
+ emit_token (TokenType.GREATER_THAN);
+ break;
+
+ case '^':
+ emit_token (TokenType.ALIGN_TOP);
+ break;
+
+ case 'v':
+ unichar next_char = get_next_char ();
+ if (_last_char.isalnum () || _last_char == ' '
+ || next_char.isalnum () || next_char == ' ') {
+ append_char (c);
+ } else {
+ emit_token (TokenType.ALIGN_BOTTOM);
+ }
+ break;
+
+ case '\'':
+ look_for_two_or_append (c, TokenType.SINGLE_QUOTE_2);
+ break;
+
+ case '/':
+ look_for_two_or_append (c, TokenType.SLASH_2);
+ break;
+
+ case '_':
+ look_for_two_or_append (c, TokenType.UNDERSCORE_2);
+ break;
+
+ case '`':
+ if (get_next_char () == '`') {
+ emit_token (TokenType.BACK_QUOTE_2);
+ _skip = 1;
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '\t':
+ emit_token (TokenType.TAB);
+ break;
+
+ case ' ':
+ emit_token (TokenType.SPACE);
+ break;
+
+ case '\r':
+ break;
+
+ case '\n':
+ emit_token (TokenType.EOL);
+ _line++;
+ _column = 0;
+ _last_column = 0;
+ break;
+
+ default:
+ append_char (c);
+ break;
+ }
+ } else {
+ _skip--;
+ }
+ _last_char = c;
+ }
+
+ private void append_char (unichar c) {
+ _current_string.append_unichar (c);
+ }
+
+ public virtual int get_line_start_column () {
+ return 0;
+ }
+
+ private SourceLocation get_begin () {
+ return SourceLocation (_last_line, get_line_start_column () + _last_column);
+ }
+
+ private SourceLocation get_end (int offset = 0) {
+ return SourceLocation (_line, get_line_start_column () + _column + offset);
+ }
+
+ private void emit_current_word () throws ParserError {
+ if (_current_string.len > 0) {
+ _parser.accept_token (new Token.from_word (_current_string.str, get_begin (), get_end (-1)));
+ _current_string.erase (0, -1);
+
+ _last_line = _line;
+ _last_column = _column - 1;
+ }
+ }
+
+ private void emit_token (TokenType type) throws ParserError {
+ emit_current_word ();
+
+ _parser.accept_token (new Token.from_type (type, get_begin (), get_end (_skip)));
+
+ _last_line = _line;
+ _last_column = _column;
+ }
+
+ private void look_for_two_or_append (unichar c, TokenType type) throws ParserError {
+ if (get_next_char () == c) {
+ emit_token (type);
+ _skip = 1;
+ } else {
+ append_char (c);
+ }
+ }
+
+ private void look_for_two (unichar c, TokenType one, TokenType two) throws ParserError {
+ if (get_next_char (1) == c) {
+ emit_token (two);
+ _skip = 1;
+ } else {
+ emit_token (one);
+ }
+ }
+
+ private void look_for_three (unichar c, TokenType one, TokenType two, TokenType three)
+ throws ParserError
+ {
+ if (get_next_char (1) == c) {
+ if (get_next_char (2) == c) {
+ emit_token (three);
+ _skip = 2;
+ } else {
+ emit_token (two);
+ _skip = 1;
+ }
+ } else {
+ emit_token (one);
+ }
+ }
+
+ private void look_for_five (unichar c, TokenType one, TokenType two, TokenType three,
+ TokenType four, TokenType five) throws ParserError
+ {
+ if (get_next_char (1) == c) {
+ if (get_next_char (2) == c) {
+ if (get_next_char (3) == c) {
+ if (get_next_char (4) == c) {
+ emit_token (five);
+ _skip = 4;
+ } else {
+ emit_token (four);
+ _skip = 3;
+ }
+ } else {
+ emit_token (three);
+ _skip = 2;
+ }
+ } else {
+ emit_token (two);
+ _skip = 1;
+ }
+ } else {
+ emit_token (one);
+ }
+ }
+
+ private bool look_for (string str, TokenType type) throws ParserError {
+ for (int i = 1; i < str.length; i++) {
+ if (get_next_char (i) != str[i]) {
+ return false;
+ }
+ }
+
+ emit_token (type);
+ _skip = (int) (str.length - 1);
+ return true;
+ }
+ }
--- /dev/null
-using Gee;
-
+ /* errorreporter.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Brosch Florian <flo.brosch@gmail.com>
+ */
+
+
+ public class Valadoc.ErrorReporter : Object {
+ private int _warnings = 0;
+ private int _errors = 0;
+
+ /**
+ * SGR end tag
+ */
+ private const string ANSI_COLOR_END = "\x1b[0m";
+
+ /**
+ * SGR start tag for source location
+ */
+ private string locus_color_start = "";
+
+ /**
+ * SGR end tag for source location
+ */
+ private unowned string locus_color_end = "";
+
+ /**
+ * SGR start tag for warning titles
+ */
+ private string warning_color_start = "";
+
+ /**
+ * SGR end tag for warning titles
+ */
+ private unowned string warning_color_end = "";
+
+ /**
+ * SGR start tag for error titles
+ */
+ private string error_color_start = "";
+
+ /**
+ * SGR end tag for error titles
+ */
+ private unowned string error_color_end = "";
+
+ /**
+ * SGR start tag for note titles
+ */
+ private string note_color_start = "";
+
+ /**
+ * SGR end tag for note titles
+ */
+ private unowned string note_color_end = "";
+
+ /**
+ * SGR start tag for caret line (^^^)
+ */
+ private string caret_color_start = "";
+
+ /**
+ * SGR end tag for caret line (^^^)
+ */
+ private unowned string caret_color_end = "";
+
+ /**
+ * SGR start tag for quotes line ('', ``, `')
+ */
+ private string quote_color_start = "";
+
+ /**
+ * SGR end tag for quotes line ('', ``, `')
+ */
+ private unowned string quote_color_end = "";
+
+
+ public int warnings_offset {
+ get;
+ set;
+ }
+
+ public int errors_offset {
+ get;
+ set;
+ }
+
+ public unowned GLib.FileStream stream {
+ get;
+ set;
+ }
+
+ public Settings? settings {
+ get;
+ set;
+ }
+
+ public int errors {
+ get {
+ return this._errors + errors_offset;
+ }
+ }
+
+ public int warnings {
+ get {
+ return this._warnings + warnings_offset;
+ }
+ }
+
+
+ public ErrorReporter (Settings? settings = null) {
+ this.stream = GLib.stderr;
+ this.settings = settings;
+ }
+
+ /**
+ * Set all colors by string
+ *
+ * {{{
+ * "error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01"
+ * }}}
+ */
+ public bool set_colors (string str) {
+ Regex val_regex;
+ try {
+ val_regex = new Regex ("^\\s*[0-9]+(;[0-9]*)*\\s*$");
+ } catch (RegexError e) {
+ assert_not_reached ();
+ }
+
+ string error_color = null;
+ string warning_color = null;
+ string note_color = null;
+ string caret_color = null;
+ string locus_color = null;
+ string quote_color = null;
+
+ string[] fragments = str.split (":");
+ foreach (unowned string fragment in fragments) {
+ string[] eq = fragment.split ("=", 2);
+ if (eq.length != 2) {
+ return false;
+ }
+
+ if (!val_regex.match (eq[1])) {
+ return false;
+ }
+
+
+ unowned string checked_value = eq[1]._strip ();
+ switch (eq[0]._strip ()) {
+ case "error":
+ error_color = checked_value;
+ break;
+
+ case "warning":
+ warning_color = checked_value;
+ break;
+
+ case "note":
+ note_color = checked_value;
+ break;
+
+ case "caret":
+ caret_color = checked_value;
+ break;
+
+ case "locus":
+ locus_color = checked_value;
+ break;
+
+ case "quote":
+ quote_color = checked_value;
+ break;
+
+ default:
+ return false;
+ }
+ }
+
+ if (is_atty (this.stream.fileno ())) {
+ if (error_color != null) {
+ this.error_color_start = "\x1b[0" + error_color + "m";
+ this.error_color_end = ANSI_COLOR_END;
+ }
+
+ if (warning_color != null) {
+ this.warning_color_start = "\x1b[0" + warning_color + "m";
+ this.warning_color_end = ANSI_COLOR_END;
+ }
+
+ if (note_color != null) {
+ this.note_color_start = "\x1b[0" + note_color + "m";
+ this.note_color_end = ANSI_COLOR_END;
+ }
+
+ if (caret_color != null) {
+ this.caret_color_start = "\x1b[0" + caret_color + "m";
+ this.caret_color_end = ANSI_COLOR_END;
+ }
+
+ if (locus_color != null) {
+ this.locus_color_start = "\x1b[0" + locus_color + "m";
+ this.locus_color_end = ANSI_COLOR_END;
+ }
+
+ if (quote_color != null) {
+ this.quote_color_start = "\x1b[0" + quote_color + "m";
+ this.quote_color_end = ANSI_COLOR_END;
+ }
+ }
+ return true;
+ }
+
+ [CCode (has_target = false)]
+ private delegate int AttyFunc (int fd);
+
+ private bool is_atty (int fd) {
+ Module module = Module.open (null, ModuleFlags.BIND_LAZY);
+ if (module == null) {
+ return false;
+ }
+
+ void* _func;
+ module.symbol ("isatty", out _func);
+ if (_func == null) {
+ return false;
+ }
+
+ AttyFunc? func = (AttyFunc) _func;
+ return func (fd) == 1;
+ }
+
+ [PrintfFormat]
+ private inline void msg (string type, string type_color_start, string type_color_end, string file, long line, long startpos, long endpos,
+ string errline, string msg_format, va_list args)
+ {
+ this.stream.printf ("%s%s:%lu.%lu-%lu.%lu:%s %s%s:%s ",
+ locus_color_start, file, line, startpos, line, endpos, locus_color_end,
+ type_color_start, type, type_color_end);
+ print_highlighted_message (msg_format.vprintf (args));
+ this.stream.putc ('\n');
+
+ if (startpos <= endpos) {
+ this.stream.printf ("%s\n", errline);
+
+ this.stream.puts (caret_color_start);
+ for (int i = 0; i < errline.char_count ()+1; i++) {
+ if (errline[i] == '\t') {
+ this.stream.printf ("\t");
+ } else if (i >= startpos - 1 && i < endpos - 1) {
+ this.stream.printf ("^");
+ } else {
+ this.stream.printf (" ");
+ }
+ }
+ this.stream.puts (caret_color_end);
+ this.stream.printf ("\n");
+ }
+ }
+
+ private void print_highlighted_message (string message) {
+ int start = 0;
+ int cur = 0;
+
+ while (message[cur] != '\0') {
+ if (message[cur] == '\'' || message[cur] == '`') {
+ unowned string end_chars = (message[cur] == '`')? "`'" : "'";
+ this.stream.puts (message.substring (start, cur - start));
+ start = cur;
+ cur++;
+
+ while (message[cur] != '\0' && end_chars.index_of_char (message[cur]) < 0) {
+ cur++;
+ }
+ if (message[cur] == '\0') {
+ this.stream.puts (message.substring (start, cur - start));
+ start = cur;
+ } else {
+ cur++;
+ this.stream.printf ("%s%s%s", quote_color_start, message.substring (start, cur - start), quote_color_end);
+ start = cur;
+ }
+ } else {
+ cur++;
+ }
+ }
+
+ this.stream.puts (message.offset (start));
+ }
+
+ [PrintfFormat]
+ public void simple_warning (string? location, string msg_format, ...) {
+ var args = va_list();
+
+ if (location != null) {
+ this.stream.puts (locus_color_start);
+ this.stream.puts (location);
+ this.stream.puts (": ");
+ this.stream.puts (locus_color_end);
+ }
+
+ this.stream.puts (warning_color_start);
+ this.stream.puts ("warning: ");
+ this.stream.puts (warning_color_end);
+
+ print_highlighted_message (msg_format.vprintf (args));
+ this.stream.putc ('\n');
+ this._warnings++;
+ }
+
+ [PrintfFormat]
+ public void simple_error (string? location, string msg_format, ...) {
+ var args = va_list();
+
+ if (location != null) {
+ this.stream.puts (locus_color_start);
+ this.stream.puts (location);
+ this.stream.puts (": ");
+ this.stream.puts (locus_color_end);
+ this.stream.putc (' ');
+ }
+
+ this.stream.puts (error_color_start);
+ this.stream.puts ("error: ");
+ this.stream.puts (error_color_end);
+
+ print_highlighted_message (msg_format.vprintf (args));
+ this.stream.putc ('\n');
+ this._errors++;
+ }
+
+ [PrintfFormat]
+ public void simple_note (string? location, string msg_format, ...) {
+ if (_settings == null || _settings.verbose) {
+ var args = va_list();
+
+ if (location != null) {
+ this.stream.puts (locus_color_start);
+ this.stream.puts (location);
+ this.stream.puts (": ");
+ this.stream.puts (locus_color_end);
+ this.stream.putc (' ');
+ }
+
+ this.stream.puts (note_color_start);
+ this.stream.puts ("note: ");
+ this.stream.puts (note_color_end);
+
+ print_highlighted_message (msg_format.vprintf (args));
+ this.stream.putc ('\n');
+ this._warnings++;
+ }
+ }
+
+ [PrintfFormat]
+ public void error (string file, long line, long startpos, long endpos, string errline,
+ string msg_format, ...)
+ {
+ var args = va_list();
+ this.msg ("error", error_color_start, error_color_end, file, line, startpos, endpos, errline, msg_format, args);
+ this._errors++;
+ }
+
+ [PrintfFormat]
+ public void warning (string file, long line, long startpos, long endpos, string errline,
+ string msg_format, ...)
+ {
+ var args = va_list();
+ this.msg ("warning", warning_color_start, warning_color_end, file, line, startpos, endpos, errline, msg_format, args);
+ this._warnings++;
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* filehelper.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Brosch Florian <flo.brosch@gmail.com>
+ */
+
+
+ namespace Valadoc {
+ [CCode (cprefix = "", cname = "PACKAGE_ICONDIR")]
+ public extern const string icons_dir;
+
+ /**
+ * Makes a copy of the file src to dest.
+ *
+ * @param src the file to copy
+ * @param dest the destination path
+ */
+ public bool copy_file (string src, string dest) {
+ GLib.FileStream fsrc = GLib.FileStream.open (src, "rb");
+ if (fsrc == null) {
+ return false;
+ }
+
+ GLib.FileStream fdest = GLib.FileStream.open (dest, "wb");
+ if (fdest == null) {
+ return false;
+ }
+
+ for (int c = fsrc.getc() ; !fsrc.eof() ; c = fsrc.getc()) {
+ fdest.putc ((char)c);
+ }
+
+ return true;
+ }
+
+ /**
+ * Makes a copy of the directory src to dest.
+ *
+ * @param src the directory to copy
+ * @param dest the destination path
+ */
+ public bool copy_directory (string src, string dest) {
+ try {
+ GLib.Dir dir = GLib.Dir.open (src);
+ for (string? file = dir.read_name (); file != null; file = dir.read_name ()) {
+ string src_file_path = GLib.Path.build_filename (src, file);
+ string dest_file_path = GLib.Path.build_filename (dest, file);
+ if (GLib.FileUtils.test (src_file_path, GLib.FileTest.IS_DIR)) {
+ GLib.DirUtils.create (dest_file_path, 0755); // mkdir if necessary
+ if (!copy_directory (src_file_path, dest_file_path)) { // copy directories recursively
+ return false;
+ }
+ } else {
+ if (!copy_file (src_file_path, dest_file_path)) {
+ return false;
+ }
+ }
+ }
+ }
+ catch (GLib.FileError err) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * A recursive directory delete function
+ *
+ * @param rpath the directory to remove
+ */
+ public bool remove_directory (string rpath) {
+ try {
+ GLib.Dir dir = GLib.Dir.open ( rpath );
+ if (dir == null)
+ return false;
+
+ for (weak string entry = dir.read_name(); entry != null ; entry = dir.read_name()) {
+ string path = rpath + entry;
+
+ bool is_dir = GLib.FileUtils.test (path, GLib.FileTest.IS_DIR);
+ if (is_dir == true) {
+ bool tmp = remove_directory (path);
+ if (tmp == false) {
+ return false;
+ }
+ } else {
+ int tmp = GLib.FileUtils.unlink (path);
+ if (tmp > 0) {
+ return false;
+ }
+ }
+ }
+ } catch (GLib.FileError err) {
+ return false;
+ }
+
+ return true;
+ }
+
+
+ private inline bool ends_with_dir_separator (string s) {
+ // --- ported from libvala ---
+ return Path.is_dir_separator (s.get_char (s.length - 1));
+ }
+
+ /**
+ * Returns canonicalized absolute pathname
+ *
+ * @param name the path being checked
+ * @return a canonicalized absolute pathname
+ */
+ public string realpath (string name) {
+ // --- ported from libvala ---
+
+ string rpath;
+
+ // start of path component
+ weak string start;
+ // end of path component
+ weak string end;
+
+ if (!Path.is_absolute (name)) {
+ // relative path
+ rpath = Environment.get_current_dir ();
+
+ start = end = name;
+ } else {
+ // set start after root
+ start = end = Path.skip_root (name);
+
+ // extract root
+ rpath = name.substring (0, (int) ((char*) start - (char*) name));
+ }
+
+ long root_len = (long) ((char*) Path.skip_root (rpath) - (char*) rpath);
+
+ for (; start.get_char () != 0; start = end) {
+ // skip sequence of multiple path-separators
+ while (Path.is_dir_separator (start.get_char ())) {
+ start = start.next_char ();
+ }
+
+ // find end of path component
+ long len = 0;
+ for (end = start; end.get_char () != 0 && !Path.is_dir_separator (end.get_char ()); end = end.next_char ()) {
+ len++;
+ }
+
+ if (len == 0) {
+ break;
+ } else if (len == 1 && start.get_char () == '.') {
+ // do nothing
+ } else if (len == 2 && start.has_prefix ("..")) {
+ // back up to previous component, ignore if at root already
+ if (rpath.length > root_len) {
+ do {
+ rpath = rpath.substring (0, rpath.length - 1);
+ } while (!ends_with_dir_separator (rpath));
+ }
+ } else {
+ if (!ends_with_dir_separator (rpath)) {
+ rpath += Path.DIR_SEPARATOR_S;
+ }
+
+ rpath += start.substring (0, len);
+ }
+ }
+
+ if (rpath.length > root_len && ends_with_dir_separator (rpath)) {
+ rpath = rpath.substring (0, rpath.length - 1);
+ }
+
+ if (Path.DIR_SEPARATOR != '/') {
+ // don't use backslashes internally,
+ // to avoid problems in #include directives
+ string[] components = rpath.split ("\\");
+ rpath = string.joinv ("/", components);
+ }
+
+ return rpath;
+ }
+ }
+
--- /dev/null
- public void append_since (Gee.List<Content.Taglet> taglets) {
+ /* gtkdocrenderer.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+ using GLib;
+ using Valadoc.Content;
+
+ public class Valadoc.GtkdocRenderer : ContentRenderer {
+ private GtkDocMarkupWriter writer = new GtkDocMarkupWriter ();
+ protected Settings settings;
+ private bool separated;
+
+ private string? get_cname (Api.Item item) {
+ if (item is Api.Method) {
+ return ((Api.Method)item).get_cname ();
+ } else if (item is Api.FormalParameter) {
+ return ((Api.FormalParameter)item).name;
+ } else if (item is Api.Constant) {
+ return ((Api.Constant)item).get_cname ();
+ } else if (item is Api.Property) {
+ return ((Api.Property)item).get_cname ();
+ } else if (item is Api.Signal) {
+ var name = ((Api.Signal)item).get_cname ();
+ return name.replace ("_", "-");
+ } else if (item is Api.Class) {
+ return ((Api.Class)item).get_cname ();
+ } else if (item is Api.Struct) {
+ return ((Api.Struct)item).get_cname ();
+ } else if (item is Api.Interface) {
+ return ((Api.Interface)item).get_cname ();
+ } else if (item is Api.ErrorDomain) {
+ return ((Api.ErrorDomain)item).get_cname ();
+ } else if (item is Api.ErrorCode) {
+ return ((Api.ErrorCode)item).get_cname ();
+ } else if (item is Api.Delegate) {
+ return ((Api.Delegate)item).get_cname ();
+ } else if (item is Api.Enum) {
+ return ((Api.Enum)item).get_cname ();
+ } else if (item is Api.EnumValue) {
+ return ((Api.EnumValue)item).get_cname ();
+ }
+
+ return null;
+ }
+
+ public void write_docbook_link (Api.Item item) {
+ writer.set_wrap (false);
+
+ if (item is Api.Method) {
+ writer.start_tag ("function")
+ .text (((Api.Method)item).get_cname ())
+ .end_tag ("function");
+ } else if (item is Api.FormalParameter) {
+ writer.start_tag ("parameter").
+ text (((Api.FormalParameter)item).name ?? "...")
+ .end_tag ("parameter");
+ } else if (item is Api.Constant) {
+ writer.start_tag ("constant").text (((Api.Constant)item)
+ .get_cname ())
+ .end_tag ("constant");
+ } else if (item is Api.Property) {
+ // TODO: use docbook-tags instead
+ writer.text ("#").text (get_cname(item.parent))
+ .text (":")
+ .text (((Api.Property)item)
+ .get_cname ().replace ("_", "-"));
+ } else if (item is Api.Signal) {
+ // TODO: use docbook-tags instead
+ writer.text ("#").text (get_cname(item.parent))
+ .text ("::")
+ .text (((Api.Signal)item).get_cname ().replace ("_", "-"));
+ } else if (item is Api.Namespace) {
+ writer.text (((Api.Namespace) item).get_full_name ());
+ } else {
+ writer.start_tag ("type")
+ .text (get_cname (item))
+ .end_tag ("type");
+ }
+
+ writer.set_wrap (true);
+ }
+
+ public GtkdocRenderer () {
+ }
+
+ public override void render (ContentElement element) {
+ reset ();
+ element.accept (this);
+ }
+
+ public void render_symbol (Content.Comment? documentation) {
+ render (documentation);
+
+ append_exceptions (documentation.find_taglets (null, typeof(Taglets.Throws)));
+ append_see (documentation.find_taglets (null, typeof(Taglets.See)));
+ append_since (documentation.find_taglets (null, typeof(Taglets.Since)));
+ }
+
+ public override void render_children (ContentElement element) {
+ reset ();
+ element.accept_children (this);
+ }
+
+ private void reset () {
+ separated = false;
+ writer.reset ();
+ }
+
+ public unowned string content {
+ get {
+ if (writer.content.has_prefix ("\n")) {
+ return writer.content.next_char ();
+ }
+
+ return writer.content;
+ }
+ }
+
+ public override void visit_comment (Comment element) {
+ element.accept_children (this);
+ }
+
+ public override void visit_embedded (Embedded element) {
+ writer.start_tag ("figure");
+ if (element.caption != null) {
+ writer.start_tag ("title")
+ .text (element.caption)
+ .end_tag ("title");
+ }
+
+ writer.start_tag ("mediaobject");
+
+ writer.start_tag ("imageobject")
+ .simple_tag ("imagedata", {"fileref", element.url})
+ .end_tag ("imageobject");
+
+ if (element.caption != null) {
+ writer.start_tag ("textobject")
+ .start_tag ("phrase")
+ .text (element.caption)
+ .end_tag ("phrase")
+ .end_tag ("textobject");
+ }
+
+ writer.end_tag ("mediaobject");
+ writer.end_tag ("figure");
+ }
+
+ public override void visit_headline (Headline element) {
+ assert_not_reached ();
+ }
+
+ public override void visit_wiki_link (WikiLink element) {
+ // wiki pages are not supported by gir
+ if (element.content.size > 0) {
+ element.accept_children (this);
+ } else {
+ write_string (element.name);
+ }
+ }
+
+ public override void visit_link (Link element) {
+ writer.start_tag ("ulink", {"url", element.url});
+ element.accept_children (this);
+ writer.end_tag ("ulink");
+ }
+
+ public override void visit_symbol_link (SymbolLink element) {
+ if (element.content.size > 0) {
+ writer.text ("\"");
+ element.accept_children (this);
+ writer.text ("\" (");
+ visit_symbol_link (element);
+ writer.text (")");
+ } else {
+ visit_symbol_link (element);
+ }
+ }
+
+ public void write_symbol_link (SymbolLink element) {
+ if (element.symbol == null) {
+ writer.text (element.given_symbol_name);
+ } else {
+ write_docbook_link (element.symbol);
+ }
+ }
+
+ public override void visit_list (Content.List element) {
+ string tag = "orderedlist";
+ switch (element.bullet) {
+ case Content.List.Bullet.NONE:
+ writer.start_tag ("itemizedlist", {"mark", "none"});
+ tag = "itemizedlist";
+ break;
+
+ case Content.List.Bullet.UNORDERED:
+ writer.start_tag ("itemizedlist");
+ tag = "itemizedlist";
+ break;
+
+ case Content.List.Bullet.ORDERED:
+ writer.start_tag ("orderedlist");
+ break;
+
+ case Content.List.Bullet.ORDERED_NUMBER:
+ writer.start_tag ("orderedlist", {"numeration", "arabic"});
+ break;
+
+ case Content.List.Bullet.ORDERED_LOWER_CASE_ALPHA:
+ writer.start_tag ("orderedlist", {"numeration", "loweralpha"});
+ break;
+
+ case Content.List.Bullet.ORDERED_UPPER_CASE_ALPHA:
+ writer.start_tag ("orderedlist", {"numeration", "upperalpha"});
+ break;
+
+ case Content.List.Bullet.ORDERED_LOWER_CASE_ROMAN:
+ writer.start_tag ("orderedlist", {"numeration", "lowerroman"});
+ break;
+
+ case Content.List.Bullet.ORDERED_UPPER_CASE_ROMAN:
+ writer.start_tag ("orderedlist", {"numeration", "upperroman"});
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+
+ element.accept_children (this);
+
+ writer.end_tag (tag);
+ }
+
+ public override void visit_list_item (ListItem element) {
+ writer.start_tag ("listitem");
+ element.accept_children (this);
+ writer.end_tag ("listitem");
+ }
+
+ public override void visit_page (Page element) {
+ element.accept_children (this);
+ }
+
+ public override void visit_paragraph (Paragraph element) {
+ writer.start_tag ("para");
+ element.accept_children (this);
+ writer.end_tag ("para");
+ }
+
+ public override void visit_warning (Warning element) {
+ writer.start_tag ("warning");
+ element.accept_children (this);
+ writer.end_tag ("warning");
+ }
+
+ public override void visit_note (Note element) {
+ writer.start_tag ("note");
+ element.accept_children (this);
+ writer.end_tag ("note");
+ }
+
+ public override void visit_run (Run element) {
+ string? tag = null;
+
+ switch (element.style) {
+ case Run.Style.BOLD:
+ writer.start_tag ("emphasis", {"role", "bold"});
+ tag = "emphasis";
+ break;
+
+ case Run.Style.ITALIC:
+ writer.start_tag ("emphasis");
+ tag = "emphasis";
+ break;
+
+ case Run.Style.UNDERLINED:
+ writer.start_tag ("emphasis", {"role", "underline"});
+ tag = "emphasis";
+ break;
+
+ case Run.Style.MONOSPACED:
+ writer.start_tag ("blockquote");
+ tag = "blockquote";
+ break;
+ }
+
+ element.accept_children (this);
+
+ if (tag != null) {
+ writer.end_tag (tag);
+ }
+ }
+
+ public override void visit_source_code (SourceCode element) {
+ writer.start_tag ("example")
+ .start_tag ("programlisting");
+ writer.text (element.code);
+ writer.end_tag ("programlisting")
+ .end_tag ("example");
+ }
+
+ public override void visit_table (Table element) {
+ writer.start_tag ("table", {"align", "center"});
+ element.accept_children (this);
+ writer.end_tag ("table");
+ }
+
+ public override void visit_table_cell (TableCell element) {
+ writer.start_tag ("td", {"colspan", element.colspan.to_string (), "rowspan", element.rowspan.to_string ()});
+ element.accept_children (this);
+ writer.end_tag ("td");
+ }
+
+ public override void visit_table_row (TableRow element) {
+ writer.start_tag ("tr");
+ element.accept_children (this);
+ writer.end_tag ("tr");
+ }
+
+ public override void visit_text (Text element) {
+ write_string (element.content);
+ }
+
+ private void write_string (string content) {
+ unichar chr = content[0];
+ long lpos = 0;
+ int i = 0;
+
+ for (i = 0; chr != '\0' ; i++, chr = content[i]) {
+ switch (chr) {
+ case '<':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text ("<");
+ lpos = i+1;
+ break;
+
+ case '>':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text (">");
+ lpos = i+1;
+ break;
+
+ case '"':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text (""");
+ lpos = i+1;
+ break;
+
+ case '\'':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text ("'");
+ lpos = i+1;
+ break;
+
+ case '&':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text ("&");
+ lpos = i+1;
+ break;
+
+ case '#':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text ("#");
+ lpos = i+1;
+ break;
+
+ case '%':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text ("%");
+ lpos = i+1;
+ break;
+
+ case '@':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text ("@");
+ lpos = i+1;
+ break;
+
+ case '(':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text ("(");
+ lpos = i+1;
+ break;
+
+ case ')':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.raw_text (")");
+ lpos = i+1;
+ break;
+
+ case '\n':
+ writer.raw_text (content.substring (lpos, i-lpos));
+ writer.simple_tag ("br");
+ lpos = i+1;
+ break;
+ }
+ }
+
+ writer.raw_text (content.substring (lpos, i-lpos));
+ }
+
- public void append_see (Gee.List<Content.Taglet> taglets) {
++ public void append_since (Vala.List<Content.Taglet> taglets) {
+ foreach (Content.Taglet _taglet in taglets) {
+ Taglets.Since taglet = _taglet as Taglets.Since;
+ if (taglet == null || taglet.version == null) {
+ // ignore unexpected taglets
+ continue ;
+ }
+
+ if (separated == false) {
+ writer.text ("\n");
+ }
+
+ writer.set_wrap (false);
+ writer.text ("\nSince: ")
+ .text (taglet.version);
+ writer.set_wrap (true);
+ separated = true;
+
+ // ignore multiple occurrences
+ return ;
+ }
+ }
+
- public void append_exceptions (Gee.List<Content.Taglet> taglets) {
++ public void append_see (Vala.List<Content.Taglet> taglets) {
+ bool first = true;
+ foreach (Content.Taglet _taglet in taglets) {
+ Taglets.See taglet = _taglet as Taglets.See;
+ if (taglet == null || taglet.symbol == null) {
+ // ignore unexpected taglets
+ continue ;
+ }
+
+ if (first) {
+ writer.start_tag ("para").text ("See also: ");
+ } else {
+ writer.text (", ");
+ }
+
+ write_docbook_link (taglet.symbol);
+ first = false;
+ }
+
+ if (first == false) {
+ writer.end_tag ("para");
+ }
+ }
+
++ public void append_exceptions (Vala.List<Content.Taglet> taglets) {
+ bool first = true;
+ foreach (Content.Taglet _taglet in taglets) {
+ Taglets.Throws taglet = _taglet as Taglets.Throws;
+ if (taglet == null || taglet.error_domain == null) {
+ // ignore unexpected taglets
+ continue ;
+ }
+
+ if (first) {
+ writer.start_tag ("para")
+ .text ("This function may throw:")
+ .end_tag ("para");
+ writer.start_tag ("table");
+ }
+
+ writer.start_tag ("tr");
+
+ writer.start_tag ("td");
+ write_docbook_link (taglet.error_domain);
+ writer.end_tag ("td");
+
+ writer.start_tag ("td");
+ taglet.accept_children (this);
+ writer.end_tag ("td");
+
+ writer.end_tag ("tr");
+
+ first = false;
+ }
+
+ if (first == false) {
+ writer.end_tag ("table");
+ }
+ }
+ }
+
--- /dev/null
- private Gee.HashMap<string, CodeTokenType?> keywords;
+ /* codescanner.vala
+ *
+ * Copyright (C) 2015 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+ using GLib;
+
+
+ /**
+ * A cheap scanner used to highlight C and Vala source code.
+ */
+ public class Valadoc.Highlighter.CodeScanner : Object, Scanner {
- Gee.HashMap<string, CodeTokenType?> keywords)
++ private Vala.HashMap<string, CodeTokenType?> keywords;
+ private bool enable_string_templates;
+ private bool enabel_verbatim_string;
+ private bool enable_preprocessor_define;
+ private bool enable_preprocessor_include;
+ private bool enable_keyword_escape;
+
+
+ private Queue<CodeToken> token_queue = new Queue<CodeToken> ();
+ private unowned string content;
+ private unowned string pos;
+
+
+ public CodeScanner (string content, bool enable_string_templates, bool enabel_verbatim_string,
+ bool enable_preprocessor_define, bool enable_preprocessor_include, bool enable_keyword_escape,
++ Vala.HashMap<string, CodeTokenType?> keywords)
+ {
+ this.content = content;
+ this.pos = content;
+
+ this.enable_string_templates = enable_string_templates;
+ this.enabel_verbatim_string = enabel_verbatim_string;
+ this.enable_preprocessor_define = enable_preprocessor_define;
+ this.enable_preprocessor_include = enable_preprocessor_include;
+ this.enable_keyword_escape = enable_keyword_escape;
+
+ this.keywords = keywords;
+ }
+
+ public CodeToken next () {
+ if (!token_queue.is_empty ()) {
+ return token_queue.pop_head ();
+ }
+
+
+ unowned string start;
+
+ for (start = pos; pos[0] != '\0'; pos = pos.next_char ()) {
+ if (((char*) pos) == ((char*) content) || pos[0] == '\n') {
+ unowned string line_start = pos;
+
+ while (pos[0] == ' ' || pos[0] == '\t' || pos[0] == '\n') {
+ pos = pos.offset (1);
+ }
+
+ if (pos[0] == '\0') {
+ break;
+ } else if (enable_preprocessor_include && pos.has_prefix ("#include")) {
+ unowned string end = pos;
+ if (queue_c_include ()) {
+ return dispatch (start, end);
+ } else {
+ pos = line_start;
+ continue;
+ }
+ } else if (pos.has_prefix ("#if") || pos.has_prefix ("#else") || pos.has_prefix ("#elif") || pos.has_prefix ("#endif")
+ || (enable_preprocessor_define && (pos.has_prefix ("#defined") || pos.has_prefix ("#ifdef")))) {
+
+ unowned string end = pos;
+ queue_until ('\n', CodeTokenType.PREPROCESSOR);
+ return dispatch (start, end);
+ }
+ }
+
+ if (pos[0] == '\'') {
+ unowned string end = pos;
+ queue_string_literal ("\'");
+ return dispatch (start, end);
+ }
+
+ if (pos[0] == '"' || (enable_string_templates && pos[0] == '@' && pos[1] == '"')) {
+ unowned string end = pos;
+ if (enabel_verbatim_string && (pos.has_prefix ("\"\"\"") || (enable_string_templates && pos.has_prefix ("@\"\"\"")))) {
+ queue_string_literal ("\"\"\"");
+ } else {
+ queue_string_literal ("\"");
+ }
+ return dispatch (start, end);
+ }
+
+ if (pos[0] >= '0' && pos[0] <= '9') {
+ unowned string end = pos;
+ queue_numeric_literal ();
+ return dispatch (start, end);
+ }
+
+ if (pos.has_prefix ("/*")) {
+ unowned string end = pos;
+ queue_multiline_comment ();
+ return dispatch (start, end);
+ }
+
+ if (pos.has_prefix ("//")) {
+ unowned string end = pos;
+ queue_until ('\n', CodeTokenType.COMMENT);
+ return dispatch (start, end);
+ }
+
+ if ((((char*) pos) == ((char*) content) || !isidstartchar (pos[-1])) && isidstartchar (pos[0])) {
+ unowned string end = pos;
+ if (queue_keyword ()) {
+ return dispatch (start, end);
+ } else {
+ continue;
+ }
+ }
+ }
+
+ token_queue.push_tail (new CodeToken (CodeTokenType.EOF, ""));
+ return dispatch (start, pos);
+ }
+
+ private bool queue_c_include () {
+ unowned string include_start = pos;
+ unowned string start = pos;
+ pos = pos.offset (8);
+
+ while (pos[0] == ' ' || pos[0] == '\t') {
+ pos = pos.offset (1);
+ }
+
+ char? end_char = null;
+ if (pos[0] == '"') {
+ end_char = '"';
+ } else if (pos[0] == '<') {
+ end_char = '>';
+ }
+
+ if (end_char != null) {
+ queue_token (start, pos, CodeTokenType.PREPROCESSOR);
+
+ unowned string literal_start = pos;
+ pos = pos.offset (1);
+
+ while (pos[0] != end_char && pos[0] != '\n' && pos[0] != '\0') {
+ pos = pos.offset (1);
+ }
+
+ if (pos[0] == end_char) {
+ pos = pos.offset (1);
+
+ queue_token (literal_start, pos, CodeTokenType.LITERAL);
+ start = pos;
+ } else {
+ pos = include_start;
+ token_queue.clear ();
+ return false;
+ }
+ }
+
+ while (pos[0] == ' ' || pos[0] == '\t') {
+ pos = pos.offset (1);
+ }
+
+ if (pos[0] == '\n' || pos[0] == '\0') {
+ queue_token (start, pos, CodeTokenType.PREPROCESSOR);
+ return true;
+ } else {
+ pos = include_start;
+ token_queue.clear ();
+ return false;
+ }
+ }
+
+ private bool queue_keyword () {
+ unowned string start = pos;
+ if (pos[0] == '@') {
+ pos = pos.offset (1);
+ }
+ while (isidchar (pos[0])) {
+ pos = pos.offset (1);
+ }
+
+ long length = start.pointer_to_offset (pos);
+ string word = start.substring (0, length);
+ CodeTokenType? token_type = keywords.get (word);
+ if (token_type == null) {
+ pos = start;
+ return false;
+ }
+
+ token_queue.push_tail (new CodeToken (token_type, word));
+ return true;
+ }
+
+ private void queue_multiline_comment () {
+ unowned string start = pos;
+ pos = pos.offset (2);
+
+ while (!(pos[0] == '*' && pos[1] == '/') && pos[0] != '\0') {
+ pos = pos.offset (1);
+ }
+
+ if (pos[0] != '\0') {
+ pos = pos.offset (2);
+ }
+
+ queue_token (start, pos, CodeTokenType.COMMENT);
+ }
+
+ private void queue_until (char end_char, CodeTokenType token_type) {
+ unowned string start = pos;
+ pos = pos.offset (1);
+
+ while (pos[0] != end_char && pos[0] != '\0') {
+ pos = pos.offset (1);
+ }
+
+ if (pos[0] != '\0' && pos[0] != '\n') {
+ pos = pos.offset (1);
+ }
+
+ queue_token (start, pos, token_type);
+ }
+
+ private void queue_string_literal (string end_chars) {
+ unowned string start = pos;
+ bool is_template = false;
+
+ if (pos[0] == '@') {
+ pos = pos.offset (end_chars.length + 1);
+ is_template = true;
+ } else {
+ pos = pos.offset (end_chars.length);
+ }
+
+ while (!pos.has_prefix (end_chars) && pos[0] != '\0') {
+ long skip = 0;
+
+ if ((pos[0] == '%' && has_printf_format_prefix (out skip))
+ || (pos[0] == '\\' && has_escape_prefix (out skip))
+ || (is_template && pos[0] == '$' && has_template_literal_prefix (out skip)))
+ {
+ queue_token (start, pos, CodeTokenType.LITERAL);
+
+ unowned string sub_start = pos;
+ pos = pos.offset (skip);
+ queue_token (sub_start, pos, CodeTokenType.ESCAPE);
+ start = pos;
+ } else {
+ pos = pos.offset (1);
+ }
+ }
+
+ if (pos[0] != '\0') {
+ pos = pos.offset (end_chars.length);
+ }
+
+ queue_token (start, pos, CodeTokenType.LITERAL);
+ }
+
+ private bool has_template_literal_prefix (out long skip) {
+ if (isidchar (pos[1])) {
+ skip = 1;
+ while (isidchar (pos[skip])) {
+ skip++;
+ }
+ return true;
+ }
+
+ if (pos[1] == '(') {
+ int level = 1;
+ skip = 2;
+
+ while (level > 0) {
+ switch (pos[skip]) {
+ case '(':
+ level++;
+ break;
+ case ')':
+ level--;
+ break;
+ case '\0':
+ skip = 0;
+ return false;
+ }
+ skip++;
+ }
+ return true;
+ }
+
+ skip = 0;
+ return false;
+ }
+
+ private bool has_escape_prefix (out long skip) {
+ switch (pos[1]) {
+ case 'a':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'v':
+ case '\\':
+ case '\'':
+ case '\"':
+ case '?':
+ skip = 2;
+ return true;
+
+ case 'x':
+ if (pos[2].isxdigit ()) {
+ for (skip = 2; pos[skip].isxdigit (); skip++) {
+ skip++;
+ }
+
+ skip++;
+ return true;
+ }
+
+ skip = 0;
+ return false;
+
+ default:
+ if (pos[1].isdigit ()) {
+ skip = 2;
+
+ if (pos[2].isdigit ()) {
+ skip++;
+
+ if (pos[3].isdigit ()) {
+ skip++;
+ }
+ }
+
+ return true;
+ }
+
+ skip = 0;
+ return false;
+ }
+ }
+
+ private bool has_printf_format_prefix (out long skip) {
+ // %[flag][min width][precision][length modifier][conversion specifier]
+ unowned string pos = this.pos;
+ unowned string start = pos;
+
+ // '%'
+ pos = pos.offset (1);
+
+ if (pos[0] == '%') {
+ pos = pos.offset (1);
+ skip = 2;
+ return true;
+ }
+
+
+ // flags:
+ while ("#0+- ".index_of_char (pos[0]) > 0) {
+ pos = pos.offset (1);
+ }
+
+ // min width:
+ while (pos[0].isdigit ()) {
+ pos = pos.offset (1);
+ }
+
+ // precision
+ if (pos[0] == '.' && pos[1].isdigit ()) {
+ pos = pos.offset (2);
+ while (pos[0].isdigit ()) {
+ pos = pos.offset (1);
+ }
+ }
+
+ // length:
+ switch (pos[0]) {
+ case 'h':
+ pos = pos.offset (1);
+ if (pos[0] == 'h') {
+ pos = pos.offset (1);
+ }
+ break;
+
+ case 'l':
+ pos = pos.offset (1);
+ if (pos[0] == 'l') {
+ pos = pos.offset (1);
+ }
+ break;
+
+ case 'j':
+ case 'z':
+ case 't':
+ case 'L':
+ pos = pos.offset (1);
+ break;
+ }
+
+ // conversion specifier:
+ switch (pos[0]) {
+ case 'd':
+ case 'i':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ case 'a':
+ case 'A':
+ case 'c':
+ case 's':
+ case 'p':
+ case 'n':
+ pos = pos.offset (1);
+ break;
+
+ default:
+ skip = 0;
+ return false;
+ }
+
+ skip = start.pointer_to_offset (pos);
+ return true;
+ }
+
+ private enum NumericType {
+ INTEGER,
+ REAL,
+ NONE
+ }
+
+ // based on libvala
+ private void queue_numeric_literal () {
+ NumericType numeric_type = NumericType.INTEGER;
+ unowned string start = pos;
+
+
+ // integer part
+ if (pos[0] == '0' && pos[1] == 'x' && pos[2].isxdigit ()) {
+ // hexadecimal integer literal
+ pos = pos.offset (2);
+ while (pos[0].isxdigit ()) {
+ pos = pos.offset (1);
+ }
+ } else {
+ // decimal number
+ while (pos[0].isdigit ()) {
+ pos = pos.offset (1);
+ }
+ }
+
+
+ // fractional part
+ if (pos[0] == '.' && pos[1].isdigit ()) {
+ numeric_type = NumericType.REAL;
+ pos = pos.offset (1);
+ while (pos[0].isdigit ()) {
+ pos = pos.offset (1);
+ }
+ }
+
+
+ // exponent part
+ if (pos[0] == 'e' || pos[0] == 'E') {
+ numeric_type = NumericType.REAL;
+ pos = pos.offset (1);
+ if (pos[0] == '+' || pos[0] == '-') {
+ pos = pos.offset (1);
+ }
+ while (pos[0].isdigit ()) {
+ pos = pos.offset (1);
+ }
+ }
+
+
+ // type suffix
+ switch (pos[0]) {
+ case 'l':
+ case 'L':
+ if (numeric_type == NumericType.INTEGER) {
+ pos = pos.offset (1);
+ if (pos[0] == 'l' || pos[0] == 'L') {
+ pos = pos.offset (1);
+ }
+ }
+ break;
+
+ case 'u':
+ case 'U':
+ if (numeric_type == NumericType.INTEGER) {
+ pos = pos.offset (1);
+ if (pos[0] == 'l' || pos[0] == 'L') {
+ pos = pos.offset (1);
+ if (pos[0] == 'l' || pos[0] == 'L') {
+ pos = pos.offset (1);
+ }
+ }
+ }
+ break;
+
+ case 'f':
+ case 'F':
+ case 'd':
+ case 'D':
+ numeric_type = NumericType.REAL;
+ pos = pos.offset (1);
+ break;
+ }
+
+ if (pos[0].isalnum ()) {
+ numeric_type = NumericType.NONE;
+ }
+
+ queue_token (start, pos, (numeric_type != NumericType.NONE)
+ ? CodeTokenType.LITERAL
+ : CodeTokenType.PLAIN);
+ }
+
+ private CodeToken dispatch (string start, string end) {
+ assert (token_queue.is_empty () == false);
+
+ if (((char*) start) == ((char*) end)) {
+ return token_queue.pop_head ();
+ }
+
+ long length = start.pointer_to_offset (end);
+ string content = start.substring (0, length);
+ return new CodeToken (CodeTokenType.PLAIN, content);
+ }
+
+ private void queue_token (string start, string end, CodeTokenType token_type) {
+ long length = start.pointer_to_offset (end);
+ string content = start.substring (0, length);
+ token_queue.push_tail (new CodeToken (token_type, content));
+ }
+
+ private inline bool isidchar (char c) {
+ return c.isalnum () || c == '_';
+ }
+
+ private inline bool isidstartchar (char c) {
+ return c.isalnum () || c == '_' || (c == '@' && enable_keyword_escape);
+ }
+ }
+
--- /dev/null
- private Gee.HashMap<string, CodeTokenType?> vala_keywords;
- private Gee.HashMap<string, CodeTokenType?> c_keywords;
+ /* codehighlighter.vala
+ *
+ * Copyright (C) 2015 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+ using GLib;
+ using Valadoc.Content;
+
+
+ public class Valadoc.Highlighter.Highlighter : Object {
- vala_keywords = new Gee.HashMap<string, CodeTokenType?> ();
++ private Vala.HashMap<string, CodeTokenType?> vala_keywords;
++ private Vala.HashMap<string, CodeTokenType?> c_keywords;
+
+
+ /**
+ * Used to highlight vala source code.
+ */
+ public Run highlight_vala (string source_code) {
+ if (vala_keywords == null) {
- c_keywords = new Gee.HashMap<string, CodeTokenType?> ();
++ vala_keywords = new Vala.HashMap<string, CodeTokenType?> (str_hash, str_equal);
+
+ // ** Types: **
+ vala_keywords.set ("string", CodeTokenType.TYPE);
+ vala_keywords.set ("bool", CodeTokenType.TYPE);
+ vala_keywords.set ("void", CodeTokenType.TYPE);
+
+ vala_keywords.set ("double", CodeTokenType.TYPE);
+ vala_keywords.set ("float", CodeTokenType.TYPE);
+
+ vala_keywords.set ("char", CodeTokenType.TYPE);
+ vala_keywords.set ("uchar", CodeTokenType.TYPE);
+ vala_keywords.set ("unichar", CodeTokenType.TYPE);
+
+ vala_keywords.set ("short", CodeTokenType.TYPE);
+ vala_keywords.set ("ushort", CodeTokenType.TYPE);
+
+ vala_keywords.set ("long", CodeTokenType.TYPE);
+ vala_keywords.set ("ulong", CodeTokenType.TYPE);
+
+ vala_keywords.set ("size_t", CodeTokenType.TYPE);
+ vala_keywords.set ("ssize_t", CodeTokenType.TYPE);
+
+ vala_keywords.set ("int", CodeTokenType.TYPE);
+ vala_keywords.set ("int8", CodeTokenType.TYPE);
+ vala_keywords.set ("int16", CodeTokenType.TYPE);
+ vala_keywords.set ("int32", CodeTokenType.TYPE);
+ vala_keywords.set ("int64", CodeTokenType.TYPE);
+
+ vala_keywords.set ("uint", CodeTokenType.TYPE);
+ vala_keywords.set ("uint8", CodeTokenType.TYPE);
+ vala_keywords.set ("uint16", CodeTokenType.TYPE);
+ vala_keywords.set ("uint32", CodeTokenType.TYPE);
+ vala_keywords.set ("uint64", CodeTokenType.TYPE);
+
+
+ // ** Literals: **
+ vala_keywords.set ("null", CodeTokenType.LITERAL);
+ vala_keywords.set ("true", CodeTokenType.LITERAL);
+ vala_keywords.set ("false", CodeTokenType.LITERAL);
+
+
+ // ** Keywords: **
+ vala_keywords.set ("return", CodeTokenType.KEYWORD);
+ vala_keywords.set ("lock", CodeTokenType.KEYWORD);
+ vala_keywords.set ("var", CodeTokenType.KEYWORD);
+ vala_keywords.set ("yield", CodeTokenType.KEYWORD);
+ vala_keywords.set ("global", CodeTokenType.KEYWORD);
+ vala_keywords.set ("construct", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("value", CodeTokenType.KEYWORD);
+ vala_keywords.set ("get", CodeTokenType.KEYWORD);
+ vala_keywords.set ("set", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("owned", CodeTokenType.KEYWORD);
+ vala_keywords.set ("unowned", CodeTokenType.KEYWORD);
+ vala_keywords.set ("const", CodeTokenType.KEYWORD);
+ vala_keywords.set ("weak", CodeTokenType.KEYWORD);
+ vala_keywords.set ("dynamic", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("out", CodeTokenType.KEYWORD);
+ vala_keywords.set ("ref", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("break", CodeTokenType.KEYWORD);
+ vala_keywords.set ("continue", CodeTokenType.KEYWORD);
+ vala_keywords.set ("return", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("if", CodeTokenType.KEYWORD);
+ vala_keywords.set ("else", CodeTokenType.KEYWORD);
+ vala_keywords.set ("switch", CodeTokenType.KEYWORD);
+ vala_keywords.set ("case", CodeTokenType.KEYWORD);
+ vala_keywords.set ("default", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("do", CodeTokenType.KEYWORD);
+ vala_keywords.set ("while", CodeTokenType.KEYWORD);
+ vala_keywords.set ("for", CodeTokenType.KEYWORD);
+ vala_keywords.set ("foreach", CodeTokenType.KEYWORD);
+ vala_keywords.set ("in", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("try", CodeTokenType.KEYWORD);
+ vala_keywords.set ("catch", CodeTokenType.KEYWORD);
+ vala_keywords.set ("finally", CodeTokenType.KEYWORD);
+ vala_keywords.set ("throw", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("class", CodeTokenType.KEYWORD);
+ vala_keywords.set ("interface", CodeTokenType.KEYWORD);
+ vala_keywords.set ("struct", CodeTokenType.KEYWORD);
+ vala_keywords.set ("enum", CodeTokenType.KEYWORD);
+ vala_keywords.set ("delegate", CodeTokenType.KEYWORD);
+ vala_keywords.set ("errordomain", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("abstract", CodeTokenType.KEYWORD);
+ vala_keywords.set ("virtual", CodeTokenType.KEYWORD);
+ vala_keywords.set ("override", CodeTokenType.KEYWORD);
+ vala_keywords.set ("signal", CodeTokenType.KEYWORD);
+ vala_keywords.set ("extern", CodeTokenType.KEYWORD);
+ vala_keywords.set ("static", CodeTokenType.KEYWORD);
+ vala_keywords.set ("async", CodeTokenType.KEYWORD);
+ vala_keywords.set ("inline", CodeTokenType.KEYWORD);
+ vala_keywords.set ("new", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("public", CodeTokenType.KEYWORD);
+ vala_keywords.set ("private", CodeTokenType.KEYWORD);
+ vala_keywords.set ("protected", CodeTokenType.KEYWORD);
+ vala_keywords.set ("internal", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("throws", CodeTokenType.KEYWORD);
+ vala_keywords.set ("requires", CodeTokenType.KEYWORD);
+ vala_keywords.set ("ensures", CodeTokenType.KEYWORD);
+ vala_keywords.set ("assert", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("namespace", CodeTokenType.KEYWORD);
+ vala_keywords.set ("using", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("as", CodeTokenType.KEYWORD);
+ vala_keywords.set ("is", CodeTokenType.KEYWORD);
+ vala_keywords.set ("in", CodeTokenType.KEYWORD);
+ vala_keywords.set ("new", CodeTokenType.KEYWORD);
+ vala_keywords.set ("delete", CodeTokenType.KEYWORD);
+ vala_keywords.set ("sizeof", CodeTokenType.KEYWORD);
+ vala_keywords.set ("typeof", CodeTokenType.KEYWORD);
+
+ vala_keywords.set ("this", CodeTokenType.KEYWORD);
+ vala_keywords.set ("base", CodeTokenType.KEYWORD);
+ }
+
+ bool enable_string_templates = true;
+ bool enable_preprocessor_define = false;
+ bool enable_preprocessor_include = false;
+ bool enable_keyword_escape = true;
+ bool enabel_verbatim_string = true;
+
+ CodeScanner scanner = new CodeScanner (source_code, enable_string_templates, enabel_verbatim_string,
+ enable_preprocessor_define, enable_preprocessor_include, enable_keyword_escape,
+ vala_keywords);
+
+ return highlight_code (scanner);
+ }
+
+ /**
+ * Used to highlight C source code.
+ */
+ public Run highlight_c (string source_code) {
+ if (c_keywords == null) {
++ c_keywords = new Vala.HashMap<string, CodeTokenType?> (str_hash, str_equal);
+
+ // ** Types: **
+ c_keywords.set ("auto", CodeTokenType.TYPE);
+ c_keywords.set ("char", CodeTokenType.TYPE);
+ c_keywords.set ("const", CodeTokenType.TYPE);
+ c_keywords.set ("double", CodeTokenType.TYPE);
+ c_keywords.set ("extern", CodeTokenType.TYPE);
+ c_keywords.set ("int", CodeTokenType.TYPE);
+ c_keywords.set ("float", CodeTokenType.TYPE);
+ c_keywords.set ("long", CodeTokenType.TYPE);
+ c_keywords.set ("register", CodeTokenType.TYPE);
+ c_keywords.set ("short", CodeTokenType.TYPE);
+ c_keywords.set ("signed", CodeTokenType.TYPE);
+ c_keywords.set ("static", CodeTokenType.TYPE);
+ c_keywords.set ("unsigned", CodeTokenType.TYPE);
+ c_keywords.set ("void", CodeTokenType.TYPE);
+ c_keywords.set ("volatile", CodeTokenType.TYPE);
+
+ c_keywords.set ("gboolean", CodeTokenType.TYPE);
+ c_keywords.set ("gpointer", CodeTokenType.TYPE);
+ c_keywords.set ("gconstpointer", CodeTokenType.TYPE);
+ c_keywords.set ("gchar", CodeTokenType.TYPE);
+ c_keywords.set ("guchar", CodeTokenType.TYPE);
+ c_keywords.set ("gint", CodeTokenType.TYPE);
+ c_keywords.set ("guint", CodeTokenType.TYPE);
+ c_keywords.set ("gshort", CodeTokenType.TYPE);
+ c_keywords.set ("gushort", CodeTokenType.TYPE);
+ c_keywords.set ("glong", CodeTokenType.TYPE);
+ c_keywords.set ("gulong", CodeTokenType.TYPE);
+ c_keywords.set ("gint8", CodeTokenType.TYPE);
+ c_keywords.set ("guint8", CodeTokenType.TYPE);
+ c_keywords.set ("gint16", CodeTokenType.TYPE);
+ c_keywords.set ("guint16", CodeTokenType.TYPE);
+ c_keywords.set ("gint32", CodeTokenType.TYPE);
+ c_keywords.set ("guint32", CodeTokenType.TYPE);
+ c_keywords.set ("gint64", CodeTokenType.TYPE);
+ c_keywords.set ("guint64", CodeTokenType.TYPE);
+ c_keywords.set ("gfloat", CodeTokenType.TYPE);
+ c_keywords.set ("gdouble", CodeTokenType.TYPE);
+ c_keywords.set ("gsize", CodeTokenType.TYPE);
+ c_keywords.set ("gssize", CodeTokenType.TYPE);
+ c_keywords.set ("goffset", CodeTokenType.TYPE);
+ c_keywords.set ("gintptr", CodeTokenType.TYPE);
+ c_keywords.set ("guintptr", CodeTokenType.TYPE);
+
+
+ // ** Literals: **
+ c_keywords.set ("NULL", CodeTokenType.LITERAL);
+ c_keywords.set ("TRUE", CodeTokenType.LITERAL);
+ c_keywords.set ("FALSE", CodeTokenType.LITERAL);
+
+
+ // ** Keywords: **
+ c_keywords.set ("break", CodeTokenType.KEYWORD);
+ c_keywords.set ("case", CodeTokenType.KEYWORD);
+ c_keywords.set ("continue", CodeTokenType.KEYWORD);
+ c_keywords.set ("default", CodeTokenType.KEYWORD);
+ c_keywords.set ("do", CodeTokenType.KEYWORD);
+ c_keywords.set ("else", CodeTokenType.KEYWORD);
+ c_keywords.set ("enum", CodeTokenType.KEYWORD);
+ c_keywords.set ("for", CodeTokenType.KEYWORD);
+ c_keywords.set ("goto", CodeTokenType.KEYWORD);
+ c_keywords.set ("if", CodeTokenType.KEYWORD);
+ c_keywords.set ("return", CodeTokenType.KEYWORD);
+ c_keywords.set ("sizeof", CodeTokenType.KEYWORD);
+ c_keywords.set ("struct", CodeTokenType.KEYWORD);
+ c_keywords.set ("switch", CodeTokenType.KEYWORD);
+ c_keywords.set ("typedef", CodeTokenType.KEYWORD);
+ c_keywords.set ("union", CodeTokenType.KEYWORD);
+ c_keywords.set ("while", CodeTokenType.KEYWORD);
+ c_keywords.set ("assert", CodeTokenType.KEYWORD);
+ }
+
+ bool enable_string_templates = false;
+ bool enable_preprocessor_define = true;
+ bool enable_preprocessor_include = true;
+ bool enable_keyword_escape = false;
+ bool enabel_verbatim_string = false;
+
+ CodeScanner scanner = new CodeScanner (source_code, enable_string_templates, enabel_verbatim_string,
+ enable_preprocessor_define, enable_preprocessor_include, enable_keyword_escape,
+ c_keywords);
+
+ return highlight_code (scanner);
+ }
+
+ /**
+ * Used to highlight C source code.
+ */
+ public Run highlight_xml (string source_code) {
+ XmlScanner scanner = new XmlScanner (source_code);
+ return highlight_code (scanner);
+ }
+
+ /**
+ * Used to highlight source code.
+ */
+ private Run highlight_code (Scanner scanner) {
+ Run code = new Run (Run.Style.MONOSPACED);
+
+ for (CodeToken token = scanner.next (); token.token_type != CodeTokenType.EOF; token = scanner.next ()) {
+ switch (token.token_type) {
+ case CodeTokenType.PREPROCESSOR:
+ Run run = new Run (Run.Style.LANG_PREPROCESSOR);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.COMMENT:
+ Run run = new Run (Run.Style.LANG_COMMENT);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.KEYWORD:
+ Run run = new Run (Run.Style.LANG_KEYWORD);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.LITERAL:
+ Run run = new Run (Run.Style.LANG_LITERAL);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.TYPE:
+ Run run = new Run (Run.Style.LANG_BASIC_TYPE);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.ESCAPE:
+ Run run = new Run (Run.Style.LANG_ESCAPE);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.XML_ESCAPE:
+ Run run = new Run (Run.Style.XML_ESCAPE);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.XML_ELEMENT:
+ Run run = new Run (Run.Style.XML_ELEMENT);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.XML_ATTRIBUTE:
+ Run run = new Run (Run.Style.XML_ATTRIBUTE);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.XML_ATTRIBUTE_VALUE:
+ Run run = new Run (Run.Style.XML_ATTRIBUTE_VALUE);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.XML_COMMENT:
+ Run run = new Run (Run.Style.XML_COMMENT);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ case CodeTokenType.XML_CDATA:
+ Run run = new Run (Run.Style.XML_CDATA);
+ run.content.add (new Text (token.content));
+ code.content.add (run);
+ break;
+
+ default:
+ code.content.add (new Text (token.content));
+ break;
+ }
+ }
+
+ return code;
+ }
+ }
+
+
--- /dev/null
- Gee.Collection<WikiPage> pages = tree.wikitree.get_pages();
+ /* basicdoclet.vala
+ *
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+ using Valadoc.Content;
+ using Valadoc.Api;
+
+
+
+ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
+ public Html.LinkHelper linker {
+ protected set;
+ get;
+ }
+
+ public Settings settings {
+ protected set;
+ get;
+ }
+
+ public string wiki_index_name {
+ default = "index.valadoc";
+ protected set;
+ get;
+ }
+
+ protected Api.Tree tree;
+ protected HtmlRenderer _renderer;
+ protected Html.MarkupWriter writer;
+ protected Html.CssClassResolver cssresolver;
+ protected Charts.Factory image_factory;
+ protected ErrorReporter reporter;
+ protected string package_list_link = "../index.html";
+
+ // CSS:
+ private const string css_inline_navigation = "navi_inline";
+ private const string css_package_index = "package_index";
+ private const string css_brief_description = "brief_description";
+ private const string css_description = "description";
+ private const string css_known_list = "known_nodes";
+ private const string css_leaf_brief_description = "leaf_brief_description";
+ private const string css_leaf_code_definition = "leaf_code_definition";
+
+ private const string css_box_headline_text = "text";
+ private const string css_box_headline_toggle = "toggle";
+ private const string css_box_headline = "headline";
+ private const string css_box_content = "content";
+ private const string css_box_column = "column";
+ private const string css_box = "box";
+
+ private const string css_namespace_note = "namespace_note";
+ private const string css_package_note = "package_note";
+
+ private const string css_site_header = "site_header";
+ private const string css_navi = "navi_main";
+ private const string css_navi_hr = "navi_hr";
+ private const string css_errordomain_table_name = "main_errordomain_table_name";
+ private const string css_errordomain_table_text = "main_errordomain_table_text";
+ private const string css_errordomain_table = "main_errordomain_table";
+ private const string css_enum_table_name = "main_enum_table_name";
+ private const string css_enum_table_text = "main_enum_table_text";
+ private const string css_enum_table = "main_enum_table";
+ private const string css_diagram = "main_diagram";
+ private const string css_see_list = "main_see_list";
+ private const string css_wiki_table = "main_table";
+ private const string css_notification_area = "main_notification";
+ private const string css_source_sample = "main_sourcesample";
+ private const string css_exception_table = "main_parameter_table";
+ private const string css_parameter_table_text = "main_parameter_table_text";
+ private const string css_parameter_table_name = "main_parameter_table_name";
+ private const string css_parameter_table = "main_parameter_table";
+ private const string css_title = "main_title";
+ private const string css_other_type = "main_other_type";
+ private const string css_basic_type = "main_basic_type";
+ private const string css_keyword = "main_keyword";
+ private const string css_optional_parameter = "main_optional_parameter";
+ private const string css_code_definition = "main_code_definition";
+ private const string css_headline_hr = "main_hr";
+ private const string css_hr = "main_hr";
+ private const string css_list_errdom = "main_list_errdom";
+ private const string css_list_en = "main_list_en";
+ private const string css_list_ns = "main_list_ns";
+ private const string css_list_cl = "main_list_cl";
+ private const string css_list_iface = "main_list_iface";
+ private const string css_list_stru = "main_list_stru";
+ private const string css_list_field = "main_list_field";
+ private const string css_list_prop = "main_list_prop";
+ private const string css_list_del = "main_list_del";
+ private const string css_list_sig = "main_list_sig";
+ private const string css_list_m = "main_list_m";
+ private const string css_style_navigation = "site_navigation";
+ private const string css_style_content = "site_content";
+ private const string css_style_body = "site_body";
+ private const string css_deprecated = "deprecated";
+
+ public virtual void process (Settings settings, Api.Tree tree, ErrorReporter reporter) {
+ this.reporter = reporter;
+ this.settings = settings;
+ this.tree = tree;
+
+ this.cssresolver = new CssClassResolver ();
+ this.linker = new LinkHelper ();
+
+ _renderer = new HtmlRenderer (settings, this.linker, this.cssresolver);
+ this.image_factory = new SimpleChartFactory (settings, linker);
+ }
+
+
+ // paths:
+ protected string? get_link (Api.Node to, Api.Node from) {
+ return linker.get_relative_link (from, to, settings);
+ }
+
+ protected virtual string get_img_path_html (Api.Node element, string type) {
+ return Path.build_filename ("img", element.get_full_name () + "." + type);
+ }
+
+ protected virtual string get_img_path (Api.Node element, string type) {
+ return Path.build_filename (settings.path, element.package.name, "img",
+ element.get_full_name () + "." + type);
+ }
+
+ protected virtual string get_icon_directory () {
+ return "..";
+ }
+
+
+ private TypeSymbol? unpack_type_reference (TypeReference? type_reference) {
+ Api.Item pos = type_reference;
+
+ while (pos != null) {
+ if (pos is TypeReference) {
+ pos = ((TypeReference) pos).data_type;
+ } else if (pos is Api.Array) {
+ pos = ((Api.Array) pos).data_type;
+ } else if (pos is Pointer) {
+ pos = ((Pointer) pos).data_type;
+ } else {
+ assert (pos is TypeSymbol);
+ return (TypeSymbol) pos;
+ }
+ }
+
+ return null;
+ }
+
+
+ protected void write_navi_entry_html_template (string style, string content, bool is_deprecated) {
+ writer.start_tag ("li", {"class", style});
+
+ if (is_deprecated) {
+ writer.start_tag ("span", {"class", css_deprecated});
+ writer.text (content);
+ writer.end_tag ("span");
+ } else {
+ writer.text (content);
+ }
+
+ writer.end_tag ("li");
+ }
+
+ protected void write_navi_entry_html_template_with_link (string style, string link,
+ string content, bool is_deprecated)
+ {
+ writer.start_tag ("li", {"class", style});
+
+ if (is_deprecated) {
+ writer.start_tag ("span", {"class", css_deprecated});
+ writer.link (link, content);
+ writer.end_tag ("span");
+ } else {
+ writer.link (link, content);
+ }
+
+ writer.end_tag ("li");
+ }
+
+ protected void write_navi_entry (Api.Node element, Api.Node? pos, string style,
+ bool link, bool full_name = false)
+ {
+ string name;
+
+ if (full_name == true && element is Namespace) {
+ string tmp = element.get_full_name();
+ name = (tmp == null)? "Global Namespace" : tmp;
+ } else {
+ string tmp = element.name;
+ name = (tmp == null)? "Global Namespace" : tmp;
+ }
+
+ bool is_deprecated = element is Symbol && ((Symbol) element).is_deprecated;
+
+ if (link == true) {
+ this.write_navi_entry_html_template_with_link (style,
+ this.get_link (element, pos),
+ name,
+ is_deprecated);
+ } else {
+ this.write_navi_entry_html_template (style, name, is_deprecated);
+ }
+ }
+
+ protected void write_wiki_pages (Api.Tree tree, string css_path_wiki, string js_path_wiki,
+ string contentp)
+ {
+ if (tree.wikitree == null) {
+ return ;
+ }
+
+ if (tree.wikitree == null) {
+ return ;
+ }
+
- Gee.ArrayList<Api.Node> lst = new Gee.ArrayList<Api.Node> ();
++ Vala.Collection<WikiPage> pages = tree.wikitree.get_pages();
+ if (pages.size == 0) {
+ return ;
+ }
+
+ DirUtils.create (contentp, 0777);
+
+ DirUtils.create (Path.build_filename (contentp, "img"), 0777);
+
+ foreach (WikiPage page in pages) {
+ if (page.name != wiki_index_name) {
+ write_wiki_page (page, contentp, css_path_wiki, js_path_wiki, this.settings.pkg_name);
+ }
+ }
+ }
+
+ protected virtual void write_wiki_page (WikiPage page, string contentp, string css_path,
+ string js_path, string pkg_name)
+ {
+ GLib.FileStream file = GLib.FileStream.open (
+ Path.build_filename (contentp, page.name.substring (0, page.name.length-7).replace ("/", ".")+"htm"),
+ "w");
+
+ writer = new MarkupWriter (file);
+ _renderer.set_writer (writer);
+ this.write_file_header (css_path, js_path, pkg_name);
+ _renderer.set_container (page);
+ _renderer.render (page.documentation);
+ this.write_file_footer ();
+ }
+
+ protected void write_navi_top_entry (Api.Node element, Api.Node? parent) {
+ string style = cssresolver.resolve (element);
+
+ writer.start_tag ("ul", {"class", css_navi});
+
+ if (element == parent || parent == null) {
+ this.write_navi_entry (element, parent, style, false);
+ } else {
+ this.write_navi_entry (element, parent, style, true);
+ }
+
+ writer.end_tag ("ul");
+ writer.simple_tag ("hr", {"class", css_navi_hr});
+ }
+
+ protected void write_top_element_template (string link) {
+ writer.start_tag ("ul", {"class", css_navi});
+ writer.start_tag ("li", {"class", css_package_index});
+ writer.link (link, "Packages");
+ writer.end_tag ("li");
+ writer.end_tag ("ul");
+ writer.simple_tag ("hr", {"class", css_navi_hr});
+ }
+
+ protected void write_top_elements (Api.Node element, Api.Node? parent) {
- protected void fetch_subnamespace_names (Api.Node node, Gee.ArrayList<Namespace> namespaces) {
- Gee.ArrayList<Api.Node> sorted_list = new Gee.ArrayList<Api.Node> ();
++ Vala.ArrayList<Api.Node> lst = new Vala.ArrayList<Api.Node> ();
+ Api.Node pos = element;
+
+ this.write_top_element_template (package_list_link);
+
+ while (pos != null) {
+ lst.add (pos);
+ pos = (Api.Node)pos.parent;
+ }
+
+ for (int i = lst.size-1; i >= 0 ; i--) {
+ Api.Node el = lst.get (i);
+
+ if (el.name != null) {
+ this.write_navi_top_entry (el, parent);
+ }
+ }
+ }
+
- sorted_list.sort ();
++ protected void fetch_subnamespace_names (Api.Node node, Vala.ArrayList<Namespace> namespaces) {
++ Vala.ArrayList<Api.Node> sorted_list = new Vala.ArrayList<Api.Node> ();
+ sorted_list.add_all (node.get_children_by_type (Api.NodeType.NAMESPACE));
- Gee.ArrayList<Namespace> ns_list = new Gee.ArrayList<Namespace> ();
++ sorted_list.sort ((CompareDataFunc) Api.Node.compare_to);
+
+ foreach (Api.Node child in sorted_list) {
+ namespaces.add ((Namespace) child);
+ this.fetch_subnamespace_names (child, namespaces);
+ }
+ }
+
+ protected void write_navi_package (Package package) {
- children.sort ();
++ Vala.ArrayList<Namespace> ns_list = new Vala.ArrayList<Namespace> ();
+ this.fetch_subnamespace_names (package, ns_list);
+
+ writer.start_tag ("div", {"class", css_style_navigation});
+ write_top_elements (package, package);
+ writer.start_tag ("ul", {"class", css_navi});
+
+ Namespace globals = null;
+
+ foreach (Namespace ns in ns_list) {
+ if (ns.name == null) {
+ globals = ns;
+ } else {
+ this.write_navi_entry (ns, package, cssresolver.resolve (ns), true, true);
+ }
+ }
+
+ if (globals != null) {
+ write_navi_children (globals, Api.NodeType.ERROR_CODE, package);
+ write_navi_children (globals, Api.NodeType.ENUM_VALUE, package);
+ write_navi_children (globals, Api.NodeType.ENUM, package);
+ write_navi_children (globals, Api.NodeType.INTERFACE, package);
+ write_navi_children (globals, Api.NodeType.CLASS, package);
+ write_navi_children (globals, Api.NodeType.STRUCT, package);
+ write_navi_children (globals, Api.NodeType.CONSTANT, package);
+ write_navi_children (globals, Api.NodeType.PROPERTY, package);
+ write_navi_children (globals, Api.NodeType.DELEGATE, package);
+ write_navi_children (globals, Api.NodeType.STATIC_METHOD, package);
+ write_navi_children (globals, Api.NodeType.CREATION_METHOD, package);
+ write_navi_children (globals, Api.NodeType.METHOD, package);
+ write_navi_children (globals, Api.NodeType.SIGNAL, package);
+ write_navi_children (globals, Api.NodeType.FIELD, package);
+ }
+
+ writer.end_tag ("ul");
+ writer.end_tag ("div");
+ }
+
+ protected void write_navi_symbol (Api.Node node) {
+ writer.start_tag ("div", {"class", css_style_navigation});
+ write_top_elements (node, node);
+ write_navi_symbol_inline (node, node);
+ writer.end_tag ("div");
+ }
+
+ protected void write_navi_leaf_symbol (Api.Node node) {
+ writer.start_tag ("div", {"class", css_style_navigation});
+ write_top_elements ((Api.Node) node.parent, node);
+ write_navi_symbol_inline ((Api.Node) node.parent, node);
+ writer.end_tag ("div");
+ }
+
+ protected void write_navi_symbol_inline (Api.Node node, Api.Node? parent) {
+ writer.start_tag ("ul", {"class", css_navi});
+ write_navi_children (node, Api.NodeType.NAMESPACE, parent);
+ write_navi_children (node, Api.NodeType.ERROR_CODE, parent);
+ write_navi_children (node, Api.NodeType.ENUM_VALUE, parent);
+ write_navi_children (node, Api.NodeType.ENUM, parent);
+ write_navi_children (node, Api.NodeType.INTERFACE, parent);
+ write_navi_children (node, Api.NodeType.CLASS, parent);
+ write_navi_children (node, Api.NodeType.STRUCT, parent);
+ write_navi_children (node, Api.NodeType.CONSTANT, parent);
+ write_navi_children (node, Api.NodeType.PROPERTY, parent);
+ write_navi_children (node, Api.NodeType.DELEGATE, parent);
+ write_navi_children (node, Api.NodeType.STATIC_METHOD, parent);
+ write_navi_children (node, Api.NodeType.CREATION_METHOD, parent);
+ write_navi_children (node, Api.NodeType.METHOD, parent);
+ write_navi_children (node, Api.NodeType.SIGNAL, parent);
+ write_navi_children (node, Api.NodeType.FIELD, parent);
+ writer.end_tag ("ul");
+ }
+
+ protected void write_navi_children (Api.Node node, Api.NodeType type, Api.Node? parent) {
+ var children = node.get_children_by_type (type);
- Gee.List<Block> description = doctree.content;
++ children.sort ((CompareDataFunc) Api.Node.compare_to);
+ foreach (Api.Node child in children) {
+ write_navi_entry (child, parent, cssresolver.resolve (child), child != parent);
+ }
+ }
+
+ protected void write_package_note (Api.Node element) {
+ string package = element.package.name;
+ if (package == null) {
+ return;
+ }
+
+ writer.start_tag ("div", {"class", css_package_note});
+ writer.start_tag ("b")
+ .text ("Package:")
+ .end_tag ("b");
+ writer.text (" ")
+ .start_tag ("a", {"href", get_link (element.package, element)})
+ .text (package)
+ .end_tag ("a");
+ writer.end_tag ("div");
+ }
+
+ protected void write_namespace_note (Api.Node element) {
+ Namespace? ns = element.nspace;
+ if (ns == null) {
+ return;
+ }
+
+ if (ns.name == null) {
+ return;
+ }
+
+ writer.start_tag ("div", {"class", css_namespace_note});
+ writer.start_tag ("b")
+ .text ("Namespace:")
+ .end_tag ("b");
+ writer.text (" ")
+ .start_tag ("a", {"href", get_link (ns, element)})
+ .text (ns.get_full_name())
+ .end_tag ("a");
+ writer.end_tag ("div");
+ }
+
+ private bool has_brief_description (Api.Node element) {
+ return element.documentation != null;
+ }
+
+ private void write_brief_description (Api.Node element , Api.Node? pos) {
+ Content.Comment? doctree = element.documentation;
+ if (doctree == null) {
+ return;
+ }
+
- private inline Gee.Collection<Api.Node> get_accessible_nodes_from_list (Gee.Collection<Api.Node> nodes) {
- var list = new Gee.ArrayList<Api.Node> ();
++ Vala.List<Block> description = doctree.content;
+ if (description.size > 0) {
+ writer.start_tag ("span", {"class", css_brief_description});
+
+ _renderer.set_container (pos);
+ _renderer.set_owner (element);
+ _renderer.render_children (description.get (0));
+ _renderer.set_owner (null);
+
+ writer.end_tag ("span");
+ }
+ }
+
+ private void write_documentation (Api.Node element , Api.Node? pos) {
+ Content.Comment? doctree = element.documentation;
+ bool is_deprecated = (element is Symbol && ((Symbol) element).is_deprecated);
+
+ // avoid empty divs
+ if (doctree == null && !is_deprecated) {
+ return;
+ }
+
+
+ writer.start_tag ("div", {"class", css_description});
+ _renderer.set_owner (element);
+
+ // deprecation warning:
+ if (is_deprecated) {
+ Symbol symbol = (Symbol) element;
+ Attribute? version;
+ Attribute? deprecated;
+ AttributeArgument? replacement;
+ AttributeArgument? since;
+ if ((version = symbol.get_attribute ("Version")) != null) {
+ replacement = version.get_argument ("replacement");
+ since = version.get_argument ("deprecated_since");
+ } else if ((deprecated = symbol.get_attribute ("Deprecated")) != null) {
+ replacement = deprecated.get_argument ("replacement");
+ since = deprecated.get_argument ("version");
+ } else {
+ assert_not_reached ();
+ }
+
+ writer.start_tag ("p");
+ writer.start_tag ("b");
+ writer.text ("Warning:");
+ writer.end_tag ("b");
+ writer.text (" %s is deprecated".printf (element.name));
+
+ if (since != null) {
+ writer.text (" since %s".printf (since.get_value_as_string ()));
+ }
+
+ writer.text (".");
+
+ if (replacement != null) {
+ string replacement_name = replacement.get_value_as_string ();
+ Api.Node? replacement_node = tree.search_symbol_str (pos,
+ replacement_name.substring (1, replacement_name.length - 2));
+
+ writer.text (" Use ");
+ if (replacement_node == null) {
+ writer.text (replacement_name);
+ } else {
+ string? link = get_link (replacement_node, pos);
+ if (link != null) {
+ string css = cssresolver.resolve (replacement_node);
+ writer.link (link, replacement_node.get_full_name (), css);
+ } else {
+ writer.start_tag ("code")
+ .text (replacement_node.get_full_name ())
+ .end_tag ("code");
+ }
+ }
+ writer.text (".");
+ }
+
+ writer.end_tag ("p");
+ }
+
+ if (doctree != null) {
+ _renderer.set_container (pos);
+ _renderer.render (doctree);
+ }
+
+
+ _renderer.set_owner (null);
+ writer.end_tag ("div");
+ }
+
+ private void write_attributes (Api.Symbol element, Api.Node? pos) {
+ writer.set_wrap (false);
+ _renderer.set_container (pos);
+ foreach (Attribute att in element.get_attributes ()) {
+ _renderer.render (att.signature);
+ writer.simple_tag ("br");
+ }
+ writer.set_wrap (true);
+ }
+
+ private void write_signature (Api.Node element , Api.Node? pos) {
+ writer.set_wrap (false);
+ _renderer.set_container (pos);
+ _renderer.render (element.signature);
+ writer.set_wrap (true);
+ }
+
+ protected bool is_internal_node (Api.Node node) {
+ return node is Package
+ || node is Api.Namespace
+ || node is Api.Interface
+ || node is Api.Class
+ || node is Api.Struct
+ || node is Api.Enum
+ || node is Api.EnumValue
+ || node is Api.ErrorDomain
+ || node is Api.ErrorCode;
+ }
+
+ public void write_navi_packages_inline (Api.Tree tree) {
+ writer.start_tag ("ul", {"class", css_navi});
+ foreach (Package pkg in tree.get_package_list()) {
+ if (pkg.is_browsable (settings)) {
+ writer.start_tag ("li", {"class", cssresolver.resolve (pkg)});
+ writer.link (linker.get_package_link (pkg, settings), pkg.name);
+ // brief description
+ writer.end_tag ("li");
+ } else {
+ writer.start_tag ("li", {"class", cssresolver.resolve (pkg)});
+ writer.text (pkg.name);
+ writer.end_tag ("li");
+ }
+ }
+ writer.end_tag ("ul");
+ }
+
+ public void write_navi_packages (Api.Tree tree) {
+ writer.start_tag ("div", {"class", css_style_navigation});
+ this.write_navi_packages_inline (tree);
+ writer.end_tag ("div");
+ }
+
+ public void write_package_index_content (Api.Tree tree) {
+ writer.start_tag ("div", {"class", css_style_content});
+ writer.start_tag ("h1", {"class", css_title})
+ .text ("Packages:")
+ .end_tag ("h1");
+ writer.simple_tag ("hr", {"class", css_headline_hr});
+
+ WikiPage? wikiindex = (tree.wikitree == null)
+ ? null
+ : tree.wikitree.search (wiki_index_name);
+ if (wikiindex != null) {
+ _renderer.set_container (wikiindex);
+ _renderer.render (wikiindex.documentation);
+ }
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Content:")
+ .end_tag ("h2");
+ writer.start_tag ("h3", {"class", css_title})
+ .text ("Packages:")
+ .end_tag ("h3");
+ this.write_navi_packages_inline (tree);
+ writer.end_tag ("div");
+ }
+
+ private uint html_id_counter = 0;
+
- private void write_known_symbols_note (Gee.Collection<Api.Node> nodes2, Api.Node container, string headline) {
++ private inline Vala.Collection<Api.Node> get_accessible_nodes_from_list (Vala.Collection<Api.Node> nodes) {
++ var list = new Vala.ArrayList<Api.Node> ();
+
+ foreach (var node in nodes) {
+ if (node.is_browsable(_settings)) {
+ list.add (node);
+ }
+ }
+
+ return list;
+ }
+
- Gee.LinkedList<Interface> printed_interfaces = new Gee.LinkedList<Interface> ();
++ private void write_known_symbols_note (Vala.Collection<Api.Node> nodes2, Api.Node container, string headline) {
+ var nodes = get_accessible_nodes_from_list (nodes2);
+ if (nodes.size == 0) {
+ return ;
+ }
+
+ // Box:
+ var html_id = "box-content-" + html_id_counter.to_string ();
+ html_id_counter++;
+
+
+ writer.start_tag ("div", {"class", css_box});
+
+ // headline:
+ writer.start_tag ("div", {"class", css_box_headline, "onclick", "toggle_box (this, '%s')".printf (html_id)})
+ .text (headline)
+ .end_tag ("div");
+ //writer.start_tag ("div", {"class", css_box_headline_text, "onclick", "toggle_box (this, '%s')".printf (html_id)})
+ // .text (headline)
+ // .end_tag ("div");
+ //writer.start_tag ("div", {"class", css_box_headline_toggle});
+ //writer.start_tag ("img", {"onclick",
+ // "toggle_box (this, '" + html_id + "')",
+ // "src",
+ // Path.build_filename (get_icon_directory (),
+ // "coll_open.png")});
+ //writer.raw_text (" ");
+ //writer.end_tag ("div");
+ //writer.end_tag ("div");
+
+
+ // content:
+ int[] list_sizes = {0, 0, 0};
+ list_sizes[0] = nodes.size;
+ list_sizes[2] = list_sizes[0]/3;
+ list_sizes[0] -= list_sizes[2];
+ list_sizes[1] = list_sizes[0]/2;
+ list_sizes[0] -= list_sizes[1];
+
+ writer.start_tag ("div", {"class", css_box_content, "id", html_id});
+
+ var iter = nodes.iterator ();
+
+ for (int i = 0; i < list_sizes.length; i++) {
+ writer.start_tag ("div", {"class", css_box_column});
+ writer.start_tag ("ul", {"class", css_inline_navigation});
+
+ for (int p = 0; p < list_sizes[i] && iter.next (); p++) {
+ var node = iter.get ();
+ writer.start_tag ("li", {"class", cssresolver.resolve (node)});
+ string link = get_link (node, container);
+ if (link == null) {
+ writer.text (node.name);
+ } else {
+ writer.link (link, node.name);
+ }
+ writer.end_tag ("li");
+ }
+
+ writer.end_tag ("ul");
+ writer.end_tag ("div");
+ }
+
+ writer.end_tag ("div"); // end content
+
+ writer.end_tag ("div"); // end box
+ }
+
+ public void write_symbol_content (Api.Node node) {
+ writer.start_tag ("div", {"class", css_style_content});
+ writer.start_tag ("h1", {"class", css_title})
+ .text (node.name)
+ .end_tag ("h1");
+ writer.simple_tag ("hr", {"class", css_headline_hr});
+ this.write_image_block (node);
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Description:")
+ .end_tag ("h2");
+ writer.start_tag ("div", {"class", css_code_definition});
+ if (node is Symbol) {
+ this.write_attributes ((Symbol) node, node);
+ }
+ this.write_signature (node, node);
+ writer.end_tag ("div");
+ this.write_documentation (node, node);
+
+ if (node is Class) {
+ var cl = node as Class;
+ write_known_symbols_note (cl.get_known_child_classes (),
+ cl,
+ "All known sub-classes:");
+ write_known_symbols_note (cl.get_known_derived_interfaces (),
+ cl,
+ "Required by:");
+ } else if (node is Interface) {
+ var iface = node as Interface;
+ write_known_symbols_note (iface.get_known_implementations (),
+ iface,
+ "All known implementing classes:");
+ write_known_symbols_note (iface.get_known_related_interfaces (),
+ iface,
+ "All known sub-interfaces:");
+ } else if (node is Struct) {
+ var stru = node as Struct;
+ write_known_symbols_note (stru.get_known_child_structs (),
+ stru,
+ "All known sub-structs:");
+ }
+
+ if (node.parent is Namespace) {
+ writer.simple_tag ("br");
+ write_namespace_note (node);
+ write_package_note (node);
+ }
+
+ if (!(node is Method || node is Delegate || node is Api.Signal)) {
+ // avoids exception listings & implementations
+
+ if (node.has_children ({
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.STATIC_METHOD,
+ Api.NodeType.CLASS,
+ Api.NodeType.STRUCT,
+ Api.NodeType.ENUM,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.METHOD,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.FIELD,
+ Api.NodeType.CONSTANT
+ }))
+ {
+ writer.start_tag ("h2", {"class", css_title}).text ("Content:").end_tag ("h2");
+ write_children (node, Api.NodeType.ERROR_CODE, "Error codes", node);
+ write_children (node, Api.NodeType.ENUM_VALUE, "Enum values", node);
+ write_children (node, Api.NodeType.CLASS, "Classes", node);
+ write_children (node, Api.NodeType.STRUCT, "Structs", node);
+ write_children (node, Api.NodeType.ENUM, "Enums", node);
+ write_children (node, Api.NodeType.CONSTANT, "Constants", node);
+ write_children (node, Api.NodeType.PROPERTY, "Properties", node);
+ write_children (node, Api.NodeType.DELEGATE, "Delegates", node);
+ write_children (node, Api.NodeType.STATIC_METHOD, "Static methods", node);
+ write_children (node, Api.NodeType.CREATION_METHOD, "Creation methods", node);
+ write_children (node, Api.NodeType.METHOD, "Methods", node);
+ write_children (node, Api.NodeType.SIGNAL, "Signals", node);
+ write_children (node, Api.NodeType.FIELD, "Fields", node);
+ }
+ }
+
+ if (node is Class) {
+ write_inherited_symbols_note_for_class ((Class) node, node);
+ } else if (node is Interface) {
+ write_inherited_symbols_note_for_interface ((Interface) node, node);
+ } else if (node is Struct) {
+ write_inherited_symbols_note_for_struct ((Struct) node, node);
+ }
+
+ writer.end_tag ("div");
+ }
+
+ private static NodeType[] inheritable_members = {
+ NodeType.CONSTANT,
+ NodeType.PROPERTY,
+ NodeType.DELEGATE,
+ NodeType.STATIC_METHOD,
+ NodeType.METHOD,
+ NodeType.SIGNAL,
+ NodeType.FIELD
+ };
+
+ private inline bool has_visible_inheritable_children (TypeSymbol symbol) {
+ return symbol.has_visible_children_by_types (inheritable_members, _settings);
+ }
+
+ private void write_inherited_members_headline () {
+ writer.start_tag ("h3", {"class", css_title})
+ .text ("Inherited Members:")
+ .end_tag ("h3");
+ }
+
+ private void write_inherited_symbols_note_for_class (Class cl, Api.Node container) {
+ bool headline_printed = false;
+
+ // class hierarchy:
+ Class base_class = unpack_type_reference (cl.base_type) as Class;
+ while (base_class != null) {
+ if (!headline_printed && has_visible_inheritable_children (base_class)) {
+ write_inherited_members_headline ();
+ headline_printed = true;
+ }
+
+ write_inherited_symbols_note (base_class, "class", container);
+ base_class = unpack_type_reference (base_class.base_type) as Class;
+ }
+
+
+ // implemented interfaces
- Gee.LinkedList<Interface> printed_interfaces = new Gee.LinkedList<Interface> ();
++ Vala.Collection<Interface> printed_interfaces = new Vala.ArrayList<Interface> ();
+ foreach (TypeReference iface_ref in cl.get_full_implemented_interface_list ()) {
+ Interface iface = (Interface) unpack_type_reference (iface_ref);
+
+ if (!headline_printed && has_visible_inheritable_children (iface)) {
+ write_inherited_members_headline ();
+ headline_printed = true;
+ } else if (printed_interfaces.contains (iface)) {
+ continue ;
+ }
+
+ write_inherited_symbols_note (iface, "interface", container);
+ printed_interfaces.add (iface);
+ }
+ }
+
+ private void write_inherited_symbols_note_for_interface (Interface iface, Api.Node container) {
+ bool headline_printed = false;
+
+ // class hierarchy:
+ Class base_class = unpack_type_reference (iface.base_type) as Class;
+ while (base_class != null) {
+ if (!headline_printed && has_visible_inheritable_children (base_class)) {
+ write_inherited_members_headline ();
+ headline_printed = true;
+ }
+
+ write_inherited_symbols_note (base_class, "class", container);
+ base_class = unpack_type_reference (base_class.base_type) as Class;
+ }
+
+
+ // interfaces:
- Gee.ArrayList<Namespace> namespaces = new Gee.ArrayList<Namespace> ();
++ Vala.Collection<Interface> printed_interfaces = new Vala.ArrayList<Interface> ();
+ foreach (TypeReference pre_ref in iface.get_full_implemented_interface_list ()) {
+ Interface pre = (Interface) unpack_type_reference (pre_ref);
+
+ if (!headline_printed && has_visible_inheritable_children (pre)) {
+ write_inherited_members_headline ();
+ headline_printed = true;
+ } else if (printed_interfaces.contains (pre)) {
+ continue ;
+ }
+
+ write_inherited_symbols_note (pre, "interface", container);
+ printed_interfaces.add (pre);
+ }
+ }
+
+ private void write_inherited_symbols_note_for_struct (Struct str, Api.Node container) {
+ Struct base_struct = unpack_type_reference (str.base_type) as Struct;
+ if (base_struct != null && has_visible_inheritable_children (base_struct)) {
+ write_inherited_members_headline ();
+ write_inherited_symbols_note (base_struct, "struct", container);
+ }
+ }
+
+ private void write_inherited_symbols_note (TypeSymbol symbol, string type, Api.Node container) {
+ write_known_symbols_note (symbol.get_children_by_types (inheritable_members, false),
+ container,
+ "All known members inherited from %s %s".printf (type, symbol.get_full_name ()));
+
+ /*
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.CONSTANT, false),
+ container,
+ "All known constants inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.PROPERTY, false),
+ container,
+ "All known properties inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.DELEGATE, false),
+ container,
+ "All known delegates inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.STATIC_METHOD, false),
+ container,
+ "All known static methods inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.METHOD, false),
+ container,
+ "All known methods inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.SIGNAL, false),
+ container,
+ "All known signals inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.FIELD, false),
+ container,
+ "All known fields inherited from %s %s".printf (type, symbol.get_full_name ()));
+ */
+ }
+
+ protected void write_child_namespaces (Api.Node node, Api.Node? parent) {
- Gee.Collection<Package>? deps = package.get_full_dependency_list ();
++ Vala.ArrayList<Namespace> namespaces = new Vala.ArrayList<Namespace> ();
+ this.fetch_subnamespace_names (node, namespaces);
+
+ if (namespaces.size == 0) {
+ return;
+ }
+
+ if (namespaces.size == 1) {
+ if (namespaces.get(0).name == null) {
+ return;
+ }
+ }
+
+ bool with_childs = parent != null && parent is Package;
+
+ writer.start_tag ("h3", {"class", css_title})
+ .text ("Namespaces:")
+ .end_tag ("h3");
+ writer.start_tag ("ul", {"class", css_inline_navigation});
+ foreach (Namespace child in namespaces) {
+ if (child.name != null) {
+ writer.start_tag ("li", {"class", cssresolver.resolve (child)});
+ writer.link (get_link (child, parent), child.name);
+ if (has_brief_description (child)) {
+ writer.text (" - ");
+ this.write_brief_description (child, parent);
+ }
+ writer.end_tag ("li");
+ if (with_childs == true) {
+ write_children (child, Api.NodeType.INTERFACE, "Interfaces", parent);
+ write_children (child, Api.NodeType.CLASS, "Classes", parent);
+ write_children (child, Api.NodeType.STRUCT, "Structs", parent);
+ write_children (child, Api.NodeType.ENUM, "Enums", parent);
+ write_children (child, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
+ write_children (child, Api.NodeType.CONSTANT, "Constants", parent);
+ write_children (child, Api.NodeType.DELEGATE, "Delegates", parent);
+ write_children (child, Api.NodeType.METHOD, "Methods", parent);
+ write_children (child, Api.NodeType.FIELD, "Fields", parent);
+ }
+ }
+ }
+ writer.end_tag ("ul");
+ }
+
+ protected void write_child_dependencies (Package package, Api.Node? parent) {
++ Vala.Collection<Package>? deps = package.get_full_dependency_list ();
+ if (deps.size == 0) {
+ return;
+ }
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Dependencies:")
+ .end_tag ("h2");
+ writer.start_tag ("ul", {"class", css_inline_navigation});
+ foreach (Package p in deps) {
+ string? link = this.get_link (p, parent);
+ if (link == null) {
+ writer.start_tag ("li", {"class", cssresolver.resolve (p), "id", p.name})
+ .text (p.name)
+ .end_tag ("li");
+ } else {
+ writer.start_tag ("li", {"class", cssresolver.resolve (p)});
+ writer.link (get_link (p, parent), p.name);
+ writer.end_tag ("li");
+ }
+ }
+ writer.end_tag ("ul");
+ }
+
+ protected void write_children (Api.Node node, Api.NodeType type, string type_string, Api.Node? container) {
+ var children = node.get_children_by_type (type);
+ if (children.size > 0) {
+ writer.start_tag ("h3", {"class", css_title})
+ .text (type_string)
+ .text (":")
+ .end_tag ("h3");
+ writer.start_tag ("ul", {"class", css_inline_navigation});
+ foreach (Api.Node child in children) {
+ writer.start_tag ("li", {"class", cssresolver.resolve (child)});
+ if (is_internal_node (child)) {
+ if (child is Symbol && ((Symbol) child).is_deprecated) {
+ writer.start_tag ("span", {"class", css_deprecated});
+ writer.link (get_link (child, container), child.name);
+ writer.end_tag ("span");
+ } else {
+ writer.link (get_link (child, container), child.name);
+ }
+ if (has_brief_description (child)) {
+ writer.text (" - ");
+ write_brief_description (child, container);
+ }
+ } else {
+ writer.start_tag ("span", {"class", css_leaf_code_definition});
+ if (child is Symbol && ((Symbol) child).is_deprecated) {
+ writer.start_tag ("span", {"class", css_deprecated});
+ write_signature (child, container);
+ writer.end_tag ("span");
+ } else {
+ write_signature (child, container);
+ }
+ writer.end_tag ("span");
+
+ writer.start_tag ("div", {"class", css_leaf_brief_description});
+ write_brief_description (child, container);
+ writer.end_tag ("div");
+ }
+ writer.end_tag ("li");
+ }
+ writer.end_tag ("ul");
+ }
+ }
+
+ protected void write_image_block (Api.Node element) {
+ if (element is Class || element is Interface || element is Struct) {
+ unowned string format = (settings.use_svg_images ? "svg" : "png");
+ var chart = new Charts.Hierarchy (image_factory, element);
+ chart.save (this.get_img_path (element, format), format);
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Object Hierarchy:")
+ .end_tag ("h2");
+
+ writer.simple_tag ("img", {"class",
+ css_diagram,
+ "usemap",
+ "#"+element.get_full_name (),
+ "alt",
+ "Object hierarchy for %s".printf (element.name),
+ "src",
+ this.get_img_path_html (element, format)});
+ writer.add_usemap (chart);
+ }
+ }
+
+ public void write_namespace_content (Namespace node, Api.Node? parent) {
+ writer.start_tag ("div", {"class", css_style_content});
+ writer.start_tag ("h1", {"class", css_title})
+ .text (node.name == null ? "Global Namespace" : node.get_full_name ())
+ .end_tag ("h1");
+ writer.simple_tag ("hr", {"class", css_hr});
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Description:")
+ .end_tag ("h2");
+
+ this.write_documentation (node, parent);
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Content:")
+ .end_tag ("h2");
+
+ if (node.name == null) {
+ this.write_child_namespaces ((Package) node.parent, parent);
+ } else {
+ this.write_child_namespaces (node, parent);
+ }
+
+ write_children (node, Api.NodeType.INTERFACE, "Interfaces", parent);
+ write_children (node, Api.NodeType.CLASS, "Classes", parent);
+ write_children (node, Api.NodeType.STRUCT, "Structs", parent);
+ write_children (node, Api.NodeType.ENUM, "Enums", parent);
+ write_children (node, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
+ write_children (node, Api.NodeType.CONSTANT, "Constants", parent);
+ write_children (node, Api.NodeType.DELEGATE, "Delegates", parent);
+ write_children (node, Api.NodeType.METHOD, "Functions", parent);
+ write_children (node, Api.NodeType.FIELD, "Fields", parent);
+ writer.end_tag ("div");
+ }
+
+ protected void write_package_content (Package node, Api.Node? parent) {
+ writer.start_tag ("div", {"class", css_style_content});
+ writer.start_tag ("h1", {"class", css_title, "id", node.name})
+ .text (node.name)
+ .end_tag ("h1");
+ writer.simple_tag ("hr", {"class", css_headline_hr});
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Description:")
+ .end_tag ("h2");
+
+
+ WikiPage? wikipage = (tree.wikitree == null)? null : tree.wikitree.search (wiki_index_name);
+ if (wikipage != null) {
+ _renderer.set_container (parent);
+ _renderer.render (wikipage.documentation);
+ }
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Content:")
+ .end_tag ("h2");
+
+ this.write_child_namespaces (node, parent);
+
+ foreach (Api.Node child in node.get_children_by_type (Api.NodeType.NAMESPACE)) {
+ if (child.name == null) {
+ write_children (child, Api.NodeType.INTERFACE, "Interfaces", parent);
+ write_children (child, Api.NodeType.CLASS, "Classes", parent);
+ write_children (child, Api.NodeType.STRUCT, "Structs", parent);
+ write_children (child, Api.NodeType.ENUM, "Enums", parent);
+ write_children (child, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
+ write_children (child, Api.NodeType.CONSTANT, "Constants", parent);
+ write_children (child, Api.NodeType.DELEGATE, "Delegates", parent);
+ write_children (child, Api.NodeType.METHOD, "Functions", parent);
+ write_children (child, Api.NodeType.FIELD, "Fields", parent);
+ }
+ }
+
+ this.write_child_dependencies (node, parent);
+ writer.end_tag ("div");
+ }
+
+ protected void write_file_header (string css, string js, string? title) {
+ writer.start_tag ("html");
+ writer.start_tag ("head");
+ writer.simple_tag ("meta", {"charset", "UTF-8"});
+ if (title == null) {
+ writer.start_tag ("title")
+ .text ("Vala Binding Reference")
+ .end_tag ("title");
+ } else {
+ writer.start_tag ("title")
+ .text (title)
+ .text (" – Vala Binding Reference")
+ .end_tag ("title");
+ }
+ writer.stylesheet_link (css);
+ writer.javascript_link (js);
+ writer.end_tag ("head");
+ writer.start_tag ("body");
+ writer.start_tag ("div", {"class", css_site_header});
+ writer.text ("%s Reference Manual".printf (title == null ? "" : title));
+ writer.end_tag ("div");
+ writer.start_tag ("div", {"class", css_style_body});
+ }
+
+ protected void write_file_footer () {
+ writer.end_tag ("div");
+ writer.simple_tag ("br");
+ writer.start_tag ("div", {"class", "site_footer"});
+ writer.text ("Generated by ");
+ writer.link ("http://www.valadoc.org/", "Valadoc");
+ writer.end_tag ("div");
+ writer.end_tag ("body");
+ writer.end_tag ("html");
+ }
+ }
+
--- /dev/null
- Gee.List<Taglet> taglets, TagletWrite write) {
+ /* htmlrenderer.vala
+ *
+ * Copyright (C) 2008-20014 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+ using GLib;
+ using Valadoc.Content;
+
+ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
+
+ protected Documentation? _container;
+ protected Documentation? _owner;
+ protected unowned MarkupWriter writer;
+ protected Html.CssClassResolver cssresolver;
+ protected LinkHelper linker;
+ protected Settings settings;
+
+ public HtmlRenderer (Settings settings, LinkHelper linker, CssClassResolver cssresolver) {
+ this.cssresolver = cssresolver;
+ this.settings = settings;
+ this.linker = linker;
+ }
+
+ public void set_container (Documentation? container) {
+ _container = container;
+ }
+
+ public void set_owner (Documentation? owner) {
+ _owner = owner;
+ }
+
+ public void set_writer (MarkupWriter writer) {
+ this.writer = writer;
+ }
+
+ public override void render (ContentElement element) {
+ element.accept (this);
+ }
+
+ public override void render_children (ContentElement element) {
+ element.accept_children (this);
+ }
+
+ private string get_url (Documentation symbol) {
+ return linker.get_relative_link (_container, symbol, settings);
+ }
+
+ private void write_unresolved_symbol_link (string given_symbol_name, InlineContent? label_owner = null) {
+ if (label_owner == null || label_owner.content.size == 0) {
+ writer.start_tag ("code");
+ writer.text (given_symbol_name);
+ writer.end_tag ("code");
+ } else {
+ writer.start_tag ("i");
+ label_owner.accept_children (this);
+ writer.end_tag ("i");
+ }
+ }
+
+ private void write_resolved_symbol_link (Api.Node symbol, string? given_symbol_name, InlineContent? label_owner = null) {
+ var symbol_name = (given_symbol_name == null || given_symbol_name == "") ? symbol.get_full_name () : given_symbol_name;
+ string href = (symbol == _container || symbol == _owner)? null : get_url (symbol);
+ string css_class = cssresolver.resolve (symbol);
+ string end_tag_name;
+
+
+ // Start Tag:
+ if (href != null) {
+ writer.start_tag ("a", {"href", href, "class", css_class});
+ end_tag_name = "a";
+ } else {
+ writer.start_tag ("span", {"class", css_class});
+ end_tag_name = "span";
+ }
+
+
+ // Content:
+ if (label_owner != null && label_owner.content.size > 0) {
+ label_owner.accept_children (this);
+ } else {
+ writer.text (symbol_name);
+ }
+
+
+ // End Tag:
+ writer.end_tag (end_tag_name);
+ }
+
+ private delegate void Write ();
+ private delegate void TagletWrite (Taglet taglet);
+
+ private void write_taglets (Write header, Write footer, Write separator,
- Gee.List<Taglet> taglets;
++ Vala.List<Taglet> taglets, TagletWrite write) {
+ if (taglets.size > 0) {
+ header ();
+ bool first = true;
+ foreach (var taglet in taglets) {
+ if (!first) {
+ separator ();
+ }
+ write (taglet);
+ first = false;
+ }
+ footer ();
+ }
+ }
+
+ public override void visit_comment (Comment element) {
++ Vala.List<Taglet> taglets;
+
+ taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Deprecated));
+ write_taglets (
+ () => {
+ writer.start_tag ("p", {"class", "main_title"});
+ writer.start_tag ("b")
+ .text ("Deprecated: ")
+ .end_tag ("b");
+ },
+ () => {
+ writer.end_tag ("p");
+ },
+ () => {},
+ taglets,
+ (taglet) => {
+ var deprecated = taglet as Taglets.Deprecated;
+ deprecated.accept_children (this);
+ });
+
+ // Write description
+ element.accept_children (this);
+
+ taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Param));
+ taglets.sort ((_a, _b) => {
+ Taglets.Param a = _a as Taglets.Param;
+ Taglets.Param b = _b as Taglets.Param;
+
+ if (a.position < 0 && b.position < 0) {
+ int cmp = a.parameter_name.ascii_casecmp (b.parameter_name);
+ if (cmp == 0) {
+ return 0;
+ }
+
+ if (a.parameter_name == "...") {
+ return 1;
+ }
+
+ if (b.parameter_name == "...") {
+ return -1;
+ }
+
+ return cmp;
+ }
+
+ if (a.position < 0) {
+ return 1;
+ }
+
+ if (b.position < 0) {
+ return -1;
+ }
+
+ return a.position - b.position;
+ });
+
+ write_taglets (
+ () => {
+ writer.start_tag ("h2", {"class", "main_title"})
+ .text ("Parameters:")
+ .end_tag ("h2");
+ writer.start_tag ("table", {"class", "main_parameter_table"});
+ },
+ () => {
+ writer.end_tag ("table");
+ },
+ () => {},
+ taglets,
+ (taglet) => {
+ var param = taglet as Taglets.Param;
+ string[]? unknown_parameter_css = null;
+ if (param.parameter == null && !param.is_this) {
+ unknown_parameter_css = {"class", "main_parameter_table_unknown_parameter"};
+ }
+
+ writer.start_tag ("tr", unknown_parameter_css);
+ writer.start_tag ("td", {"class", "main_parameter_table_name"})
+ .text (param.parameter_name)
+ .end_tag ("td");
+ writer.start_tag ("td");
+ param.accept_children (this);
+ writer.end_tag ("td");
+ writer.end_tag ("tr");
+ });
+
+ taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Return));
+ write_taglets (
+ () => {
+ writer.start_tag ("h2", {"class", "main_title"})
+ .text ("Returns:")
+ .end_tag ("h2");
+ writer.start_tag ("table", {"class", "main_parameter_table"});
+ },
+ () => {
+ writer.end_tag ("table");
+ },
+ () => {},
+ taglets,
+ (taglet) => {
+ var param = taglet as Taglets.Return;
+ writer.start_tag ("tr");
+ writer.start_tag ("td");
+ param.accept_children (this);
+ writer.end_tag ("td");
+ writer.end_tag ("tr");
+ });
+
+ taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Throws));
+ write_taglets (
+ () => {
+ writer.start_tag ("h2", {"class", "main_title"})
+ .text ("Exceptions:")
+ .end_tag ("h2");
+ writer.start_tag ("table", {"class", "main_parameter_table"});
+ },
+ () => {
+ writer.end_tag ("table");
+ },
+ () => {},
+ taglets,
+ (taglet) => {
+ var exception = taglet as Taglets.Throws;
+ writer.start_tag ("tr");
+ writer.start_tag ("td", {"class", "main_parameter_table_name"})
+ .text (exception.error_domain_name)
+ .end_tag ("td");
+ writer.start_tag ("td");
+ exception.accept_children (this);
+ writer.end_tag ("td");
+ writer.end_tag ("tr");
+ });
+
+ taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Since));
+ write_taglets (
+ () => {
+ writer.start_tag ("h2", {"class", "main_title"})
+ .text ("Since:")
+ .end_tag ("h2");
+ writer.start_tag ("p");
+ },
+ () => {
+ writer.end_tag ("p");
+ },
+ () => {},
+ taglets,
+ (taglet) => {
+ var since = taglet as Taglets.Since;
+ writer.text (since.version);
+ });
+
+ taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.See));
+ write_taglets (
+ () => {
+ writer.start_tag ("h2", {"class", "main_title"})
+ .text ("See also:")
+ .end_tag ("h2");
+ writer.start_tag ("p");
+ },
+ () => {
+ writer.end_tag ("p");
+ },
+ () => {
+ writer.text (", ");
+ },
+ taglets,
+ (taglet) => {
+ var see = taglet as Taglets.See;
+ if (see.symbol == null) {
+ write_unresolved_symbol_link (see.symbol_name);
+ } else {
+ write_resolved_symbol_link (see.symbol, see.symbol_name);
+ }
+ });
+ }
+
+ public override void visit_embedded (Embedded element) {
+ var caption = element.caption;
+
+ var absolute_path = Path.build_filename (settings.path, element.package.name, "img",
+ Path.get_basename (element.url));
+ var relative_path = Path.build_filename ("img", Path.get_basename (element.url));
+
+ copy_file (element.url, absolute_path);
+
+ writer.image (relative_path, (caption == null || caption == "") ? "" : caption);
+ }
+
+ public override void visit_headline (Headline element) {
+ writer.start_tag ("h%d".printf (element.level));
+ element.accept_children (this);
+ writer.end_tag ("h%d".printf (element.level));
+ }
+
+ public override void visit_wiki_link (WikiLink element) {
+ if (element.page != null) {
+ writer.start_tag ("a", {"href", get_url (element.page)});
+ }
+
+ if (element.content.size > 0) {
+ element.accept_children (this);
+ } else {
+ writer.text (element.name.substring (0, element.name.last_index_of_char ('.')));
+ }
+
+ if (element.page != null) {
+ writer.end_tag ("a");
+ }
+ }
+
+ public override void visit_link (Link element) {
+ if (Uri.parse_scheme (element.url) != null) {
+ writer.start_tag ("a", {"href", element.url, "target", "_blank"});
+ } else {
+ writer.start_tag ("a", {"href", element.url});
+ }
+
+ if (element.content.size > 0) {
+ element.accept_children (this);
+ } else {
+ writer.text (element.url);
+ }
+
+ writer.end_tag ("a");
+ }
+
+ public override void visit_symbol_link (SymbolLink element) {
+ if (element.symbol == null) {
+ write_unresolved_symbol_link (element.given_symbol_name, element);
+ } else {
+ write_resolved_symbol_link (element.symbol, element.given_symbol_name, element);
+ }
+ }
+
+ public override void visit_list (Content.List element) {
+ string list_type = null;
+ string bullet_type = null;
+ string css_class = null;
+ switch (element.bullet) {
+ case Content.List.Bullet.NONE:
+ list_type = "ul";
+ css_class = "no_bullet";
+ break;
+ case Content.List.Bullet.UNORDERED:
+ list_type = "ul";
+ break;
+ case Content.List.Bullet.ORDERED:
+ list_type = "ol";
+ break;
+ case Content.List.Bullet.ORDERED_NUMBER:
+ list_type = "ol";
+ bullet_type = "1";
+ break;
+ case Content.List.Bullet.ORDERED_LOWER_CASE_ALPHA:
+ list_type = "ol";
+ bullet_type = "a";
+ break;
+ case Content.List.Bullet.ORDERED_UPPER_CASE_ALPHA:
+ list_type = "ol";
+ bullet_type = "A";
+ break;
+ case Content.List.Bullet.ORDERED_LOWER_CASE_ROMAN:
+ list_type = "ol";
+ bullet_type = "i";
+ break;
+ case Content.List.Bullet.ORDERED_UPPER_CASE_ROMAN:
+ list_type = "ol";
+ bullet_type = "I";
+ break;
+ }
+ writer.start_tag (list_type, {"class", css_class, "type", bullet_type});
+ element.accept_children (this);
+ writer.end_tag (list_type);
+ }
+
+ public override void visit_list_item (ListItem element) {
+ writer.start_tag ("li");
+ Paragraph? first_para = (element.content.size > 0)? element.content[0] as Paragraph : null;
+ if (first_para != null) {
+ // We do not pick up alignments in gir-files.
+ first_para.accept_children (this);
+ bool first_entry = true;
+ foreach (var item in element.content) {
+ if (!first_entry) {
+ item.accept (this);
+ }
+ first_entry = false;
+ }
+ } else {
+ element.accept_children (this);
+ }
+ writer.end_tag ("li");
+ }
+
+ public override void visit_page (Page element) {
+ element.accept_children (this);
+ }
+
+ public override void visit_paragraph (Paragraph element) {
+ //FIXME: the extra-field is just a workarround for the current codegen ...
+ if (element.horizontal_align == null) {
+ writer.start_tag ("p");
+ } else {
+ HorizontalAlign tmp = element.horizontal_align;
+ switch (tmp) {
+ case HorizontalAlign.CENTER:
+ writer.start_tag ("p", {"style", "text-align: center;"});
+ break;
+
+ case HorizontalAlign.RIGHT:
+ writer.start_tag ("p", {"style", "text-align: right;"});
+ break;
+
+ default:
+ writer.start_tag ("p");
+ break;
+ }
+ }
+ element.accept_children (this);
+ writer.end_tag ("p");
+ }
+
+ private void visit_notification_block (BlockContent element, string headline) {
+ writer.start_tag ("div", {"class", "main_notification_block"});
+ writer.start_tag ("span", {"class", "main_block_headline"})
+ .text (headline)
+ .end_tag ("span")
+ .text (" ");
+ writer.start_tag ("div", {"class", "main_block_content"});
+ element.accept_children (this);
+ writer.end_tag ("div");
+ writer.end_tag ("div");
+ }
+
+ public override void visit_warning (Warning element) {
+ visit_notification_block (element, "Warning:");
+ }
+
+ public override void visit_note (Note element) {
+ visit_notification_block (element, "Note:");
+ }
+
+ public override void visit_run (Run element) {
+ string tag = null;
+ string css_type = null;
+ switch (element.style) {
+ case Run.Style.BOLD:
+ tag = "b";
+ break;
+ case Run.Style.ITALIC:
+ tag = "i";
+ break;
+ case Run.Style.UNDERLINED:
+ tag = "u";
+ break;
+ case Run.Style.MONOSPACED:
+ tag = "code";
+ break;
+ case Run.Style.STROKE:
+ tag = "stroke";
+ break;
+ case Run.Style.LANG_KEYWORD:
+ tag = "span";
+ css_type = "main_keyword";
+ break;
+ case Run.Style.LANG_ESCAPE:
+ tag = "span";
+ css_type = "main_escape";
+ break;
+ case Run.Style.LANG_LITERAL:
+ tag = "span";
+ css_type = "main_literal";
+ break;
+ case Run.Style.LANG_BASIC_TYPE:
+ tag = "span";
+ css_type = "main_basic_type";
+ break;
+ case Run.Style.LANG_TYPE:
+ tag = "span";
+ css_type = "main_type";
+ break;
+ case Run.Style.LANG_COMMENT:
+ tag = "span";
+ css_type = "main_comment";
+ break;
+ case Run.Style.LANG_PREPROCESSOR:
+ tag = "span";
+ css_type = "main_preprocessor";
+ break;
+
+ case Run.Style.XML_ESCAPE:
+ tag = "span";
+ css_type = "xml_escape";
+ break;
+
+ case Run.Style.XML_ELEMENT:
+ tag = "span";
+ css_type = "xml_element";
+ break;
+
+ case Run.Style.XML_ATTRIBUTE:
+ tag = "span";
+ css_type = "xml_attribute";
+ break;
+
+ case Run.Style.XML_ATTRIBUTE_VALUE:
+ tag = "span";
+ css_type = "xml_attribute_value";
+ break;
+
+ case Run.Style.XML_COMMENT:
+ tag = "span";
+ css_type = "xml_comment";
+ break;
+
+ case Run.Style.XML_CDATA:
+ tag = "span";
+ css_type = "xml_cdata";
+ break;
+ }
+ if (tag != null) {
+ writer.start_tag (tag, {"class", css_type});
+ }
+ element.accept_children (this);
+ if (tag != null) {
+ writer.end_tag (tag);
+ }
+ }
+
+ public override void visit_source_code (SourceCode element) {
+ writer.set_wrap (false);
+ writer.start_tag ("pre", {"class", "main_source"});
+ element.accept_children (this);
+ writer.end_tag ("pre");
+ writer.set_wrap (true);
+ }
+
+ public override void visit_table (Table element) {
+ writer.start_tag ("table", {"class", "main_table"});
+ element.accept_children (this);
+ writer.end_tag ("table");
+ }
+
+ public override void visit_table_cell (TableCell element) {
+ string style = "";
+
+ if (element.horizontal_align != null) {
+ style += "text-align: "+element.horizontal_align.to_string ()+"; ";
+ }
+
+ if (element.vertical_align != null) {
+ style += "vertical-align: "+element.vertical_align.to_string ()+"; ";
+ }
+
+ writer.start_tag ("td", {"class", "main_table",
+ "colspan", element.colspan.to_string (),
+ "rowspan", element.rowspan.to_string (),
+ "style", style});
+ element.accept_children (this);
+ writer.end_tag ("td");
+ }
+
+ public override void visit_table_row (TableRow element) {
+ writer.start_tag ("tr");
+ element.accept_children (this);
+ writer.end_tag ("tr");
+ }
+
+ public override void visit_taglet (Taglet element) {
+ }
+
+ public override void visit_text (Text element) {
+ write_string (element.content);
+ }
+
+ private void write_string (string content) {
+ unichar chr = content[0];
+ long lpos = 0;
+ int i = 0;
+
+ for (i = 0; chr != '\0' ; i++, chr = content[i]) {
+ switch (chr) {
+ case '\n':
+ writer.text (content.substring (lpos, i-lpos));
+ writer.simple_tag ("br");
+ lpos = i+1;
+ break;
+ case '<':
+ writer.text (content.substring (lpos, i-lpos));
+ writer.text ("<");
+ lpos = i+1;
+ break;
+ case '>':
+ writer.text (content.substring (lpos, i-lpos));
+ writer.text (">");
+ lpos = i+1;
+ break;
+ case '&':
+ writer.text (content.substring (lpos, i-lpos));
+ writer.text ("&");
+ lpos = i+1;
+ break;
+ }
+ }
+ writer.text (content.substring (lpos, i-lpos));
+ }
+ }
+
--- /dev/null
-using Gee;
-
-
+ /* linkhelper.vala
+ *
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ public class Valadoc.Html.LinkHelper : Object {
+ protected Settings _settings = null;
+
+ public bool enable_browsable_check {
+ default = true;
+ get;
+ set;
+ }
+
+ public virtual string? get_package_link (Api.Package package, Settings settings) {
+ if (enable_browsable_check && !package.is_browsable (settings)) {
+ return null;
+ }
+
+ return Path.build_filename (package.name, "index.htm");
+ }
+
+ public string? get_relative_link (Documentation from, Documentation to, Settings settings) {
+ _settings = settings;
+
+ //TODO: find a better solution which does not require too much code ...
+ if (from is Api.Package) {
+ if (to is Api.Package) {
+ return from_package_to_package ((Api.Package) from, (Api.Package) to);
+ } else if (to is Api.Node) {
+ return from_package_to_node ((Api.Package) from, (Api.Node) to);
+ } else if (to is WikiPage) {
+ return from_package_to_wiki ((Api.Package) from, (WikiPage) to);
+ } else {
+ assert (true);
+ }
+ } else if (from is Api.Node) {
+ if (to is Api.Package) {
+ return from_node_to_package ((Api.Node) from, (Api.Package) to);
+ } else if (to is Api.Node) {
+ return from_node_to_node ((Api.Node) from, (Api.Node) to);
+ } else if (to is WikiPage) {
+ return from_node_to_wiki ((Api.Node) from, (WikiPage) to);
+ } else {
+ assert (true);
+ }
+ } else if (from is WikiPage) {
+ if (to is Api.Package) {
+ return from_wiki_to_package ((WikiPage) from, (Api.Package) to);
+ } else if (to is Api.Node) {
+ return from_wiki_to_node ((WikiPage) from, (Api.Node) to);
+ } else if (to is WikiPage) {
+ return from_wiki_to_wiki ((WikiPage) from, (WikiPage) to);
+ } else {
+ assert (true);
+ }
+ } else {
+ assert (true);
+ }
+
+ return null;
+ }
+
+ protected string translate_wiki_name (WikiPage page) {
+ var name = page.name;
+ return name.substring (0, name.last_index_of_char ('.')).replace ("/", ".") + ".htm";
+ }
+
+
+
+
+ protected virtual string? from_package_to_package (Api.Package from, Api.Package to) {
+ if (enable_browsable_check && !to.is_browsable(_settings)) {
+ return null;
+ }
+
+ if (from == to) {
+ return "#";
+ } else {
+ return Path.build_filename ("..", to.name, "index.htm");
+ }
+ }
+
+ protected virtual string? from_package_to_wiki (Api.Package from, WikiPage to) {
+ if (from.is_package) {
+ return Path.build_filename ("..", _settings.pkg_name, translate_wiki_name (to));
+ } else {
+ return translate_wiki_name (to);
+ }
+ }
+
+ protected virtual string? from_package_to_node (Api.Package from, Api.Node to) {
+ if (enable_browsable_check && (!to.is_browsable(_settings) || !to.package.is_browsable (_settings))) {
+ return null;
+ }
+
+ if (from == to.package) {
+ return Path.build_filename (to.get_full_name () + ".html");
+ } else {
+ return Path.build_filename ("..", to.package.name, to.get_full_name () + ".html");
+ }
+ }
+
+
+
+ protected virtual string? from_wiki_to_package (WikiPage from, Api.Package to) {
+ if (enable_browsable_check && !to.is_browsable(_settings)) {
+ return null;
+ }
+
+ if (to.is_package) {
+ return Path.build_filename ("..", to.name, "index.htm");
+ } else {
+ return "index.htm";
+ }
+ }
+
+ protected virtual string? from_wiki_to_wiki (WikiPage from, WikiPage to) {
+ return translate_wiki_name (to);
+ }
+
+ protected virtual string? from_wiki_to_node (WikiPage from, Api.Node to) {
+ if (enable_browsable_check && (!to.is_browsable(_settings) || !to.package.is_browsable (_settings))) {
+ return null;
+ }
+
+ if (to.package.is_package) {
+ return Path.build_filename ("..", to.package.name, to.get_full_name () + ".html");
+ } else {
+ return to.get_full_name () + ".html";
+ }
+ }
+
+
+
+ protected virtual string? from_node_to_package (Api.Node from, Api.Package to) {
+ if (enable_browsable_check && !to.is_browsable (_settings)) {
+ return null;
+ }
+
+ if (from.package == to) {
+ return "index.htm";
+ } else {
+ return Path.build_filename ("..", to.name, "index.htm");
+ }
+ }
+
+ protected virtual string? from_node_to_wiki (Api.Node from, WikiPage to) {
+ if (from.package.is_package) {
+ return Path.build_filename ("..", _settings.pkg_name, translate_wiki_name (to));
+ } else {
+ return translate_wiki_name (to);
+ }
+ }
+
+ protected virtual string? from_node_to_node (Api.Node from, Api.Node to) {
+ if (enable_browsable_check && (!to.is_browsable(_settings) || !to.package.is_browsable (_settings))) {
+ return null;
+ }
+
+ if (from.package == to.package) {
+ return Path.build_filename (to.get_full_name() + ".html");
+ } else {
+ return Path.build_filename ("..", to.package.name, to.get_full_name() + ".html");
+ }
+ }
+ }
+
--- /dev/null
-using Gee;
-
-
+ /* resourcelocator.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ public abstract class Valadoc.Importer.DocumentationImporter : Object, ResourceLocator {
+ protected ModuleLoader modules;
+ protected Settings settings;
+ protected Api.Tree tree;
+
+ public abstract string file_extension { get; }
+
+ public DocumentationImporter (Api.Tree tree, ModuleLoader modules, Settings settings) {
+ this.settings = settings;
+ this.modules = null;
+ this.tree = tree;
+ }
+
+ public virtual string resolve (string path) {
+ return path;
+ }
+
+ public abstract void process (string filename);
+ }
+
+
--- /dev/null
-using GLib;
-using Gee;
-
+ /* girdocumentationimporter.vala
+ *
+ * Copyright (C) 2008-2010 Jürg Billeter
+ * Copyright (C) 2011 Luca Bruno
+ * Copyright (C) 2011-2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Jürg Billeter <j@bitron.ch>
+ * Luca Bruno <lucabru@src.gnome.org>
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc;
- Gee.List<Api.Node> parameters = node.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false);
+
+ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
+ public override string file_extension {
+ get {
+ return "gir";
+ }
+ }
+
+ private MarkupTokenType current_token;
+ private MarkupSourceLocation begin;
+ private MarkupSourceLocation end;
+ private MarkupReader reader;
+
+ private DocumentationParser parser;
+ private ErrorReporter reporter;
+ private Api.SourceFile file;
+
+ private string parent_c_identifier;
+
+ private struct ImplicitParameterPos {
+ public int parameter;
+ public int position;
+
+ public ImplicitParameterPos (int parameter, int position) {
+ this.parameter = parameter;
+ this.position = position;
+ }
+ }
+
+ public GirDocumentationImporter (Api.Tree tree, DocumentationParser parser,
+ ModuleLoader modules, Settings settings,
+ ErrorReporter reporter)
+ {
+ base (tree, modules, settings);
+ this.reporter = reporter;
+ this.parser = parser;
+ }
+
+ public override void process (string source_file) {
+ this.file = new Api.SourceFile (new Api.Package (Path.get_basename (source_file), true, null),
+ source_file, null, null);
+ this.reader = new MarkupReader (source_file, reporter);
+
+ // xml prolog
+ next ();
+ next ();
+
+ next ();
+ parse_repository ();
+
+ reader = null;
+ file = null;
+ }
+
+ private Api.FormalParameter? find_parameter (Api.Node node, string name) {
- // Skip <annotation /> (only generated by valac) and <attribute />
- if (current_token == MarkupTokenType.START_ELEMENT
- && (reader.name == "annotation" || reader.name == "attribute")) {
- next (); // MarkupTokenType.END_ELEMENT, annotation / attribute
++ Vala.List<Api.Node> parameters = node.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false);
+ foreach (Api.Node param in parameters) {
+ if (((Api.FormalParameter) param).name == name) {
+ return (Api.FormalParameter) param;
+ }
+ }
+
+ return null;
+ }
+
+ private inline string? get_cparameter_name (string[] param_names, int length_pos) {
+ if (length_pos < 0 || param_names.length < length_pos) {
+ return null;
+ }
+
+ return param_names[length_pos];
+ }
+
+ private void attach_comment (string cname,
+ Api.GirSourceComment? comment,
+ string[]? param_names = null,
+ ImplicitParameterPos[]? destroy_notifies = null,
+ ImplicitParameterPos[]? closures = null,
+ ImplicitParameterPos[]? array_lengths = null,
+ int array_length_ret = -1)
+ {
+ if (comment == null) {
+ return ;
+ }
+
+ Api.Node? node = this.tree.search_symbol_cstr (null, cname);
+ if (node == null) {
+ return;
+ }
+
+ if (param_names != null) {
+ foreach (ImplicitParameterPos pos in destroy_notifies) {
+ Api.FormalParameter? param = find_parameter (node, param_names[pos.parameter]);
+ if (param == null) {
+ continue ;
+ }
+
+ param.implicit_destroy_cparameter_name
+ = get_cparameter_name (param_names, pos.position);
+ }
+
+ foreach (ImplicitParameterPos pos in closures) {
+ Api.FormalParameter? param = find_parameter (node, param_names[pos.parameter]);
+ if (param == null) {
+ continue ;
+ }
+
+ param.implicit_closure_cparameter_name
+ = get_cparameter_name (param_names, pos.position);
+ }
+
+ foreach (ImplicitParameterPos pos in array_lengths) {
+ Api.FormalParameter? param = find_parameter (node, param_names[pos.parameter]);
+ if (param == null) {
+ continue ;
+ }
+
+ param.implicit_array_length_cparameter_name
+ = get_cparameter_name (param_names, pos.position);
+ }
+
+ if (node is Api.Callable) {
+ ((Api.Callable) node).implicit_array_length_cparameter_name
+ = get_cparameter_name (param_names, array_length_ret);
+ }
+ }
+
+ Content.Comment? content = this.parser.parse (node, comment);
+ if (content == null) {
+ return;
+ }
+
+ node.documentation = content;
+ }
+
+ private void warning (string message) {
+ reporter.warning (this.file.relative_path, this.begin.line, this.begin.column, this.end.column,
+ this.reader.get_line_content (this.begin.line), message);
+ }
+
+ private void error (string message) {
+ reporter.error (this.file.relative_path, this.begin.line, this.begin.column, this.end.column,
+ this.reader.get_line_content (this.begin.line), message);
+ }
+
+ private void next () {
+ current_token = reader.read_token (out begin, out end);
+
++ // Skip <annotation /> (only generated by valac)
++ if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "annotation") {
++ next (); // MarkupTokenType.END_ELEMENT, annotation
+ next ();
+ }
+ }
+
+ private void start_element (string name) {
+ if (current_token != MarkupTokenType.START_ELEMENT || reader.name != name) {
+ // error
+ error ("expected start element of `%s'".printf (name));
+ }
+ }
+
+ private void end_element (string name) {
+ if (current_token != MarkupTokenType.END_ELEMENT || reader.name != name) {
+ // error
+ error ("expected end element of `%s'".printf (name));
+ }
+ next ();
+ }
+
+ private const string GIR_VERSION = "1.2";
+
+ private void parse_repository () {
+ start_element ("repository");
+ if (reader.get_attribute ("version") != GIR_VERSION) {
+ error ("unsupported GIR version %s (supported: %s)"
+ .printf (reader.get_attribute ("version"), GIR_VERSION));
+ return;
+ }
+ next ();
+
+ while (current_token == MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "namespace") {
+ parse_namespace ();
+ } else if (reader.name == "include") {
+ parse_include ();
+ } else if (reader.name == "package") {
+ parse_package ();
+ } else if (reader.name == "c:include") {
+ parse_c_include ();
+ } else {
+ // error
+ error ("unknown child element `%s' in `repository'".printf (reader.name));
+ skip_element ();
+ }
+ }
+ end_element ("repository");
+ }
+
+ private void parse_include () {
+ start_element ("include");
+ next ();
+
+ end_element ("include");
+ }
+
+ private void parse_package () {
+ start_element ("package");
+ next ();
+
+ end_element ("package");
+ }
+
+ private void parse_c_include () {
+ start_element ("c:include");
+ next ();
+
+ end_element ("c:include");
+ }
+
+ private void skip_element () {
+ next ();
+
+ int level = 1;
+ while (level > 0) {
+ if (current_token == MarkupTokenType.START_ELEMENT) {
+ level++;
+ } else if (current_token == MarkupTokenType.END_ELEMENT) {
+ level--;
+ } else if (current_token == MarkupTokenType.EOF) {
+ error ("unexpected end of file");
+ break;
+ }
+ next ();
+ }
+ }
+
+ private void parse_namespace () {
+ start_element ("namespace");
+
+ next ();
+ while (current_token == MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "alias") {
+ parse_alias ();
+ } else if (reader.name == "enumeration") {
+ parse_enumeration ();
+ } else if (reader.name == "bitfield") {
+ parse_bitfield ();
+ } else if (reader.name == "function") {
+ parse_method ("function");
+ } else if (reader.name == "callback") {
+ parse_callback ();
+ } else if (reader.name == "record") {
+ parse_record ();
+ } else if (reader.name == "class") {
+ parse_class ();
+ } else if (reader.name == "interface") {
+ parse_interface ();
+ } else if (reader.name == "glib:boxed") {
+ parse_boxed ("glib:boxed");
+ } else if (reader.name == "union") {
+ parse_union ();
+ } else if (reader.name == "constant") {
+ parse_constant ();
+ } else {
+ // error
+ error ("unknown child element `%s' in `namespace'".printf (reader.name));
+ skip_element ();
+ }
+ }
+
+ end_element ("namespace");
+ }
+
+ private void parse_alias () {
+ start_element ("alias");
+ string c_identifier = reader.get_attribute ("c:type");
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ attach_comment (c_identifier, comment);
+
+ parse_type ();
+
+ end_element ("alias");
+ }
+
+ private Api.GirSourceComment? parse_symbol_doc () {
+ Api.GirSourceComment? comment = null;
+
+ if (reader.name == "doc") {
+ start_element ("doc");
+ next ();
+
+
+ if (current_token == MarkupTokenType.TEXT) {
+ comment = new Api.GirSourceComment (reader.content, file, begin.line,
+ begin.column, end.line, end.column);
+ next ();
+ }
+
+ end_element ("doc");
+ }
+
+ while (true) {
+ if (reader.name == "doc-deprecated") {
+ Api.SourceComment? doc_deprecated = parse_doc ("doc-deprecated");
+ if (doc_deprecated != null) {
+ if (comment == null) {
+ comment = new Api.GirSourceComment ("", file, begin.line, end.line,
+ begin.line, end.line);
+ }
+
+ comment.deprecated_comment = doc_deprecated;
+ }
+ } else if (reader.name == "doc-version") {
+ Api.SourceComment? doc_version = parse_doc ("doc-version");
+ if (doc_version != null) {
+ if (comment == null) {
+ comment = new Api.GirSourceComment ("", file, begin.line, end.line,
+ begin.line, end.line);
+ }
+
+ comment.version_comment = doc_version;
+ }
+ } else if (reader.name == "doc-stability") {
+ Api.SourceComment? doc_stability = parse_doc ("doc-stability");
+ if (doc_stability != null) {
+ if (comment == null) {
+ comment = new Api.GirSourceComment ("", file, begin.line, end.line,
+ begin.line, end.line);
+ }
+
+ comment.stability_comment = doc_stability;
+ }
+ } else {
+ break;
+ }
+ }
+
+ return comment;
+ }
+
+ private Api.SourceComment? parse_doc (string element_name = "doc") {
+ if (reader.name != element_name) {
+ return null;
+ }
+
+ start_element (element_name);
+ next ();
+
+ Api.SourceComment? comment = null;
+
+ if (current_token == MarkupTokenType.TEXT) {
+ comment = new Api.SourceComment (reader.content, file, begin.line,
+ begin.column, end.line, end.column);
+ next ();
+ }
+
+ end_element (element_name);
+ return comment;
+ }
+
+ private void parse_enumeration (string element_name = "enumeration") {
+ start_element (element_name);
+ this.parent_c_identifier = reader.get_attribute ("c:type");
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ attach_comment (this.parent_c_identifier, comment);
+
+ while (current_token == MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "member") {
+ parse_enumeration_member ();
+ } else if (reader.name == "function") {
+ skip_element ();
+ } else {
+ // error
+ error ("unknown child element `%s' in `%s'".printf (reader.name, element_name));
+ skip_element ();
+ }
+ }
+
+ this.parent_c_identifier = null;
+ end_element (element_name);
+ }
+
+ private void parse_bitfield () {
+ parse_enumeration ("bitfield");
+ }
+
+ private void parse_enumeration_member () {
+ start_element ("member");
+ string c_identifier = reader.get_attribute ("c:identifier");
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ attach_comment (c_identifier, comment);
+
+ end_element ("member");
+ }
+
+ private void parse_return_value (out Api.SourceComment? comment, out int array_length_ret) {
+ start_element ("return-value");
+ next ();
+
+ comment = parse_doc ();
+
+ parse_type (out array_length_ret);
+
+ end_element ("return-value");
+ }
+
+ private void parse_parameter (out Api.SourceComment? comment, out string param_name,
+ out int destroy_pos,
+ out int closure_pos, out int array_length_pos) {
+ start_element ("parameter");
+ param_name = reader.get_attribute ("name");
+ array_length_pos = -1;
+ destroy_pos = -1;
+ closure_pos = -1;
+
+ string? closure = reader.get_attribute ("closure");
+ if (closure != null) {
+ closure_pos = int.parse (closure);
+ if (closure_pos < 0) {
+ warning ("invalid closure position");
+ }
+ }
+
+ string? destroy = reader.get_attribute ("destroy");
+ if (destroy != null) {
+ destroy_pos = int.parse (destroy);
+ if (destroy_pos < 0) {
+ warning ("invalid destroy position");
+ }
+ }
+ next ();
+
+ comment = parse_doc ();
+
+ if (reader.name == "varargs") {
+ start_element ("varargs");
+ param_name = "...";
+ next ();
+
+ end_element ("varargs");
+ } else {
+ parse_type (out array_length_pos);
+ }
+
+ end_element ("parameter");
+ }
+
+ private void parse_type (out int array_length_pos = null) {
+ array_length_pos = -1;
+
+ if (reader.name == "array") {
+ string? length = reader.get_attribute ("length");
+ if (length != null) {
+ array_length_pos = int.parse (length);
+ if (array_length_pos < 0) {
+ warning ("invalid array lenght position");
+ }
+ }
+
+ skip_element ();
+ } else {
+ skip_element ();
+ }
+ }
+
+ private void parse_record () {
+ start_element ("record");
+ this.parent_c_identifier = reader.get_attribute ("c:type");
+ if (this.parent_c_identifier.has_suffix ("Private")) {
+ this.parent_c_identifier = null;
+ skip_element ();
+ return ;
+ }
+
+ bool is_type_struct = (reader.get_attribute ("glib:is-gtype-struct-for") != null);
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ if (is_type_struct == false) {
+ attach_comment (this.parent_c_identifier, comment);
+ }
+
+ while (current_token == MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "constructor") {
+ parse_constructor ();
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "function") {
+ skip_element ();
+ } else if (reader.name == "union") {
+ parse_union ();
+ } else {
+ // error
+ error ("unknown child element `%s' in `record'".printf (reader.name));
+ skip_element ();
+ }
+ }
+
+ this.parent_c_identifier = null;
+ end_element ("record");
+ }
+
+ private void parse_class () {
+ start_element ("class");
+ this.parent_c_identifier = reader.get_attribute ("c:type");
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ attach_comment (this.parent_c_identifier, comment);
+
+ while (current_token == MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "implements") {
+ skip_element ();
+ } else if (reader.name == "constant") {
+ parse_constant ();
+ } else if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "property") {
+ parse_property ();
+ } else if (reader.name == "constructor") {
+ parse_constructor ();
+ } else if (reader.name == "function") {
+ parse_method ("function");
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "virtual-method") {
+ parse_method ("virtual-method");
+ } else if (reader.name == "union") {
+ parse_union ();
+ } else if (reader.name == "glib:signal") {
+ parse_signal ();
+ } else {
+ // error
+ error ("unknown child element `%s' in `class'".printf (reader.name));
+ skip_element ();
+ }
+ }
+
+ this.parent_c_identifier = null;
+ end_element ("class");
+ }
+
+ private void parse_interface () {
+ start_element ("interface");
+ this.parent_c_identifier = reader.get_attribute ("c:type");
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ attach_comment (this.parent_c_identifier, comment);
+
+ while (current_token == MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "prerequisite") {
+ skip_element ();
+ } else if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "property") {
+ parse_property ();
+ } else if (reader.name == "virtual-method") {
+ parse_method ("virtual-method");
+ } else if (reader.name == "function") {
+ parse_method ("function");
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "glib:signal") {
+ parse_signal ();
+ } else {
+ // error
+ error ("unknown child element `%s' in `interface'".printf (reader.name));
+ skip_element ();
+ }
+ }
+
+ this.parent_c_identifier = null;
+ end_element ("interface");
+ }
+
+ private void parse_field () {
+ start_element ("field");
+ string c_identifier = reader.get_attribute ("name");
+ if (this.parent_c_identifier != null) {
+ c_identifier = this.parent_c_identifier + "." + c_identifier;
+ }
+ next ();
+
+ parse_symbol_doc ();
+
+ parse_type ();
+
+ end_element ("field");
+ }
+
+ private void parse_property () {
+ start_element ("property");
+ string c_identifier = "%s:%s".printf (parent_c_identifier, reader.get_attribute ("name")
+ .replace ("-", "_"));
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ attach_comment (c_identifier, comment);
+
+ parse_type ();
+
+ end_element ("property");
+ }
+
+ private void parse_callback () {
+ parse_function ("callback");
+ }
+
+ private void parse_constructor () {
+ parse_function ("constructor");
+ }
+
+ private void parse_function (string element_name) {
+ start_element (element_name);
+
+ string? c_identifier = null;
+ switch (element_name) {
+ case "constructor":
+ case "function":
+ case "method":
+ c_identifier = reader.get_attribute ("c:identifier");
+ break;
+
+ case "callback":
+ c_identifier = reader.get_attribute ("c:type");
+ break;
+
+ case "virtual-method":
+ c_identifier = "%s->%s".printf (this.parent_c_identifier, reader.get_attribute ("name")
+ .replace ("-", "_"));
+ break;
+
+ case "glib:signal":
+ c_identifier = "%s::%s".printf (this.parent_c_identifier, reader.get_attribute ("name")
+ .replace ("-", "_"));
+ break;
+
+ default:
+ skip_element ();
+ return ;
+ }
+
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+
+ ImplicitParameterPos[] destroy_notifies = new ImplicitParameterPos[0];
+ ImplicitParameterPos[] array_lengths = new ImplicitParameterPos[0];
+ ImplicitParameterPos[] closures = new ImplicitParameterPos[0];
+ string[] param_names = new string[0];
+ int array_length_ret = -1;
+
+ if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "return-value") {
+ Api.SourceComment? return_comment;
+ parse_return_value (out return_comment, out array_length_ret);
+ if (return_comment != null) {
+ if (comment == null) {
+ comment = new Api.GirSourceComment ("", file, begin.line, begin.column,
+ end.line, end.column);
+ }
+ comment.return_comment = return_comment;
+ }
+ }
+
+
+ if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
+ start_element ("parameters");
+ next ();
+
+ if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "instance-parameter") {
+ string instance_param_name = reader.get_attribute ("name");
+ next ();
+
+ Api.SourceComment? param_comment = parse_doc ();
+ parse_type (null);
+ end_element ("instance-parameter");
+
+ if (param_comment != null) {
+ if (comment == null) {
+ comment = new Api.GirSourceComment ("", file, begin.line, begin.column,
+ end.line, end.column);
+ }
+
+ comment.add_parameter_content (instance_param_name, param_comment);
+ comment.instance_param_name = instance_param_name;
+ }
+ }
+
+ for (int pcount = 0; current_token == MarkupTokenType.START_ELEMENT; pcount++) {
+ Api.SourceComment? param_comment;
+ int array_length_pos;
+ int destroy_pos;
+ int closure_pos;
+ string? param_name;
+
+ parse_parameter (out param_comment, out param_name, out destroy_pos,
+ out closure_pos, out array_length_pos);
+ param_names += param_name;
+
+ if (destroy_pos >= 0 && pcount != destroy_pos) {
+ destroy_notifies += ImplicitParameterPos (pcount, destroy_pos);
+ }
+
+ if (closure_pos >= 0 && pcount != closure_pos) {
+ closures += ImplicitParameterPos (pcount, closure_pos);
+ }
+
+ if (array_length_pos >= 0 && pcount != destroy_pos) {
+ array_lengths += ImplicitParameterPos (pcount, array_length_pos);
+ }
+
+ if (param_comment != null) {
+ if (comment == null) {
+ comment = new Api.GirSourceComment ("", file, begin.line, begin.column,
+ end.line, end.column);
+ }
+
+ comment.add_parameter_content (param_name, param_comment);
+ }
+ }
+ end_element ("parameters");
+ }
+
+ attach_comment (c_identifier, comment, param_names, destroy_notifies, closures,
+ array_lengths, array_length_ret);
+
+ end_element (element_name);
+ }
+
+ private void parse_method (string element_name) {
+ parse_function (element_name);
+ }
+
+ private void parse_signal () {
+ parse_function ("glib:signal");
+ }
+
+ private void parse_boxed (string element_name) {
+ start_element (element_name);
+
+ this.parent_c_identifier = reader.get_attribute ("name");
+ if (this.parent_c_identifier == null) {
+ this.parent_c_identifier = reader.get_attribute ("glib:name");
+ }
+
+ next ();
+
+ parse_symbol_doc ();
+
+ // TODO: process comments
+
+ while (current_token == MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "constructor") {
+ parse_constructor ();
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "function") {
+ skip_element ();
+ } else if (reader.name == "union") {
+ parse_union ();
+ } else {
+ // error
+ error ("unknown child element `%s' in `class'".printf (reader.name));
+ skip_element ();
+ }
+ }
+
+ this.parent_c_identifier = null;
+ end_element (element_name);
+ }
+
+ private void parse_union () {
+ start_element ("union");
+ this.parent_c_identifier = reader.get_attribute ("c:type");
+ if (this.parent_c_identifier == null) {
+ skip_element ();
+ return ;
+ }
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ attach_comment (this.parent_c_identifier, comment);
+
+ while (current_token == MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "constructor") {
+ parse_constructor ();
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "function") {
+ skip_element ();
+ } else if (reader.name == "record") {
+ parse_record ();
+ } else {
+ // error
+ error ("unknown child element `%s' in `union'".printf (reader.name));
+ skip_element ();
+ }
+ }
+
+ this.parent_c_identifier = null;
+ end_element ("union");
+ }
+
+ private void parse_constant () {
+ start_element ("constant");
+ string c_identifier = reader.get_attribute ("c:type");
+ next ();
+
+ Api.GirSourceComment? comment = parse_symbol_doc ();
+ attach_comment (c_identifier, comment);
+
+ parse_type ();
+
+ end_element ("constant");
+ }
+ }
+
--- /dev/null
-using Valadoc;
-using Gee;
+ /* gtkdocindexsgmlreader.vala
+ *
+ * Copyright (C) 2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private HashMap<string, Api.Node> symbol_map;
- private HashMap<string, string> map;
+
++using Valadoc;
+
+ public class Valadoc.Importer.InternalIdRegistrar {
- map = new HashMap<string, string> ();
- symbol_map = new HashMap<string, Api.Node> ();
++ private Vala.HashMap<string, Api.Node> symbol_map;
++ private Vala.HashMap<string, string> map;
+
+
+ public InternalIdRegistrar () {
++ map = new Vala.HashMap<string, string> (str_hash, str_equal);
++ symbol_map = new Vala.HashMap<string, Api.Node> (str_hash, str_equal);
+ }
+
+
+ public void register_symbol (string id, Api.Node symbol) {
+ this.symbol_map.set (id, symbol);
+ }
+
+ public string? map_url_id (string id) {
+ return map.get (id);
+ }
+
+ public Api.Node? map_symbol_id (string id) {
+ return symbol_map.get (id);
+ }
+
+
+ public void read_index_sgml_file (string filename, string? index_sgml_online, ErrorReporter reporter) {
+ MarkupSourceLocation begin;
+ MarkupSourceLocation end;
+ MarkupTokenType token;
+
+ string base_path = index_sgml_online ?? realpath (filename);
+ var reader = new MarkupReader (filename, reporter);
+
+ while ((token = reader.read_token (out begin, out end)) != MarkupTokenType.EOF) {
+ if (token == MarkupTokenType.START_ELEMENT && reader.name == "ONLINE") {
+ if (index_sgml_online == null) {
+ base_path = reader.get_attribute ("href");
+ if (base_path == null) {
+ reporter.error (filename, begin.line, begin.column, end.column, reader.get_line_content (begin.line), "missing attribute `href' in <ONLINE>");
+ }
+ }
+ } else if (token == MarkupTokenType.START_ELEMENT && reader.name == "ANCHOR") {
+ string id = reader.get_attribute ("id");
+ if (id == null) {
+ reporter.error (filename, begin.line, begin.column, end.column, reader.get_line_content (begin.line), "missing attribute `id' in <ANCHOR>");
+ }
+
+ string href = reader.get_attribute ("href");
+ if (href == null) {
+ reporter.error (filename, begin.line, begin.column, end.column, reader.get_line_content (begin.line), "missing attribute `href' in <ANCHOR>");
+ } else if (index_sgml_online != null) {
+ href = Path.get_basename (href);
+ }
+
+ map.set (id, Path.build_path ("/", base_path, href));
+ } else {
+ reporter.error (filename, begin.line, begin.column, end.column, reader.get_line_content (begin.line), "expected element of <ONLINE> or <ANCHOR>");
+ }
+ }
+ }
+ }
+
+
--- /dev/null
-using Gee;
+ /* resourcelocator.vala
+ *
+ * Copyright (C) 2010 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc;
+ using Valadoc.Content;
+
+ public class Valadoc.Importer.ValadocDocumentationImporter : DocumentationImporter, ResourceLocator {
+ public override string file_extension { get { return "valadoc"; } }
+
+ private ValadocDocumentationScanner _scanner;
+ private DocumentationParser _doc_parser;
+ private Parser _parser;
+
+ private MappedFile _mapped_file;
+ private string _filename;
+ private string _cname;
+ private StringBuilder _comment;
+ private SourceLocation _comment_location;
+ protected Content.ContentFactory factory;
+
+
+ private ErrorReporter reporter;
+
+ public ValadocDocumentationImporter (Api.Tree tree, DocumentationParser parser, ModuleLoader modules,
+ Settings settings, ErrorReporter reporter)
+ {
+ base (tree, modules, settings);
+ this.factory = new Content.ContentFactory (settings, this, modules);
+ this.reporter = reporter;
+
+ _scanner = new ValadocDocumentationScanner (settings);
+ _doc_parser = parser;
+
+ _scanner = new ValadocDocumentationScanner (settings);
+ _parser = new Parser (settings, _scanner, reporter);
+ _scanner.set_parser (_parser);
+
+ _comment = new StringBuilder ();
+
+ // init parser rules:
+ Rule unprinted_spaces = Rule.many ({
+ Rule.one_of ({
+ TokenType.VALADOC_SPACE,
+ TokenType.VALADOC_TAB
+ })
+ });
+
+ Rule empty_lines = Rule.many ({
+ Rule.one_of ({
+ unprinted_spaces,
+ TokenType.VALADOC_EOL
+ })
+ })
+ .set_name ("EmptyLines");
+
+ Rule optional_empty_lines = Rule.option ({
+ empty_lines
+ });
+
+ Rule documentation = Rule.one_of ({
+ Rule.seq ({
+ TokenType.VALADOC_COMMENT_START.action ((token) => { _comment_location = token.end; }),
+ Rule.many ({
+ Rule.one_of ({
+ TokenType.ANY_WORD.action ((token) => { _comment.append (token.to_string ()); }),
+ TokenType.VALADOC_COMMENT_START.action ((token) => { _comment.append (token.to_string ()); }),
+ TokenType.VALADOC_SPACE.action ((token) => { _comment.append (token.to_string ()); }),
+ TokenType.VALADOC_TAB.action ((token) => { _comment.append (token.to_string ()); }),
+ TokenType.VALADOC_EOL.action ((token) => { _comment.append (token.to_string ()); })
+ })
+ }),
+ TokenType.VALADOC_COMMENT_END,
+ optional_empty_lines,
+ TokenType.ANY_WORD.action ((token) => { _cname = token.to_string (); })
+ })
+ .set_reduce (() => {
+ add_documentation (_cname, _comment, _filename, _comment_location);
+ _comment.erase ();
+ _cname = null;
+ }),
+
+ TokenType.ANY_WORD.action ((token) => {
+ add_documentation (token.to_string (), null, _filename, _comment_location);
+ })
+ })
+ .set_name ("Documentation");
+
+ Rule file = Rule.many ({
+ Rule.one_of ({
+ documentation,
+ optional_empty_lines
+ })
+ })
+ .set_name ("ValadocFile");
+
+ _parser.set_root_rule (file);
+ }
+
+ private enum InsertionMode {
+ APPEND,
+ PREPEND,
+ REPLACE
+ }
+
+ private void add_documentation (string _symbol_name, StringBuilder? comment, string filename,
+ SourceLocation src_ref)
+ {
+ Api.Node? symbol = null;
+
+ InsertionMode insertion_mode;
+ string symbol_name;
+ if (_symbol_name.has_suffix ("::append")) {
+ symbol_name = _symbol_name.substring (0, _symbol_name.length - 8);
+ insertion_mode = InsertionMode.APPEND;
+ } else if (_symbol_name.has_suffix ("::prepend")) {
+ symbol_name = _symbol_name.substring (0, _symbol_name.length - 9);
+ insertion_mode = InsertionMode.PREPEND;
+ } else {
+ symbol_name = _symbol_name;
+ insertion_mode = InsertionMode.REPLACE;
+ }
+
+ if (symbol_name.has_prefix ("c::")) {
+ symbol = tree.search_symbol_cstr (null, symbol_name.substring (3));
+ } else {
+ symbol = tree.search_symbol_str (null, symbol_name);
+ }
+
+ if (symbol == null) {
+ if (settings.verbose) {
+ reporter.simple_warning (filename, "Node `%s' does not exist", symbol_name);
+ }
+
+ return ;
+ }
+
+ if (comment != null) {
+ var docu = _doc_parser.parse_comment_str (symbol, comment.str, filename, src_ref.line, src_ref.column);
+ if (docu != null) {
+ docu.check (tree, symbol, filename, reporter, settings);
+
+ if (symbol.documentation == null || insertion_mode == InsertionMode.REPLACE) {
+ if (insertion_mode == InsertionMode.APPEND) {
+ docu.content.insert (0, factory.create_paragraph ());
+ }
+ symbol.documentation = docu;
+ } else if (insertion_mode == InsertionMode.APPEND) {
+ symbol.documentation.content.add_all (docu.content);
+ merge_taglets (symbol.documentation, docu);
+ } else if (insertion_mode == InsertionMode.PREPEND) {
+ symbol.documentation.content.insert_all (0, docu.content);
+ merge_taglets (symbol.documentation, docu);
+ }
+ }
+ }
+ }
+
+ private void merge_taglets (Comment comment, Comment imported) {
+ foreach (Taglet taglet in imported.taglets) {
+ imported.taglets.add (taglet);
+ }
+ }
+
+ public override void process (string filename) {
+ try {
+ _filename = filename;
+ _mapped_file = new MappedFile (filename, false);
+ var content = _mapped_file.get_contents ();
+ if (content != null) {
+ _parser.parse ((string) content, filename, 0, 0);
+ }
+ } catch (FileError err) {
+ reporter.simple_error (null, "Unable to map file `%s': %s", filename, err.message);
+ } catch (ParserError err) {
+ }
+ }
+ }
+
--- /dev/null
+ /* valadodocumentationscanner.vala
+ *
+ * Copyright (C) 2010 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
++
+ public class Valadoc.Importer.ValadocDocumentationScanner : Object, Scanner {
+
+ public ValadocDocumentationScanner (Settings settings) {
+ _settings = settings;
+ }
+
+ private Settings _settings;
+ private Parser _parser;
+
+ private string _content;
+ private unowned string _index;
+ private bool _stop;
+ private int _last_line;
+ private int _last_column;
+ private int _line;
+ private int _column;
+ private unichar _last_char;
+ private int _skip;
+ private StringBuilder _current_string = new StringBuilder ();
+
+ public void set_parser (Parser parser) {
+ _parser = parser;
+ }
+
+ public virtual void reset () {
+ _stop = false;
+ _last_line = 0;
+ _last_column = 0;
+ _line = 0;
+ _column = 0;
+ _last_char = 0;
+ _skip = 0;
+ _current_string.erase (0, -1);
+ }
+
+ public void scan (string content) throws ParserError {
+ this._content = content;
+
+ for (_index = _content; !_stop && _index.get_char () != 0; _index = _index.next_char ()) {
+ unichar c = _index.get_char ();
+ accept (c);
+ }
+ }
+
+ public void end () throws ParserError {
+ emit_token (TokenType.EOF);
+ }
+
+ public virtual void stop () {
+ _stop = true;
+ }
+
+ public int get_line () {
+ return _line;
+ }
+
+ public virtual string get_line_content () {
+ StringBuilder builder = new StringBuilder ();
+ weak string line_start = _index;
+ unichar c;
+
+ while ((char*) line_start > (char*) _content && line_start.prev_char ().get_char () != '\n') {
+ line_start = line_start.prev_char ();
+ }
+
+ while ((c = line_start.get_char ()) != '\n' && c != '\0') {
+ if (c == '\t') {
+ builder.append_c (' ');
+ } else {
+ builder.append_unichar (c);
+ }
+ line_start = line_start.next_char ();
+ }
+
+ return builder.str;
+ }
+
+ protected unichar get_next_char (int offset = 1) {
+ return _index.get_char (_index.index_of_nth_char (offset));
+ }
+
+
+ protected void accept (unichar c) throws ParserError {
+ _column++;
+ if (_skip == 0) {
+ switch (c) {
+ case '/':
+ if (get_next_char (1) == '*') {
+ emit_token (TokenType.VALADOC_COMMENT_START);
+ _skip = 1;
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '*':
+ if (get_next_char (1) == '/') {
+ emit_token (TokenType.VALADOC_COMMENT_END);
+ _skip = 1;
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '\t':
+ emit_token (TokenType.VALADOC_TAB);
+ break;
+
+ case ' ':
+ emit_token (TokenType.VALADOC_SPACE);
+ break;
+
+ case '\n':
+ emit_token (TokenType.VALADOC_EOL);
+ _line++;
+ _column = 0;
+ _last_column = 0;
+ break;
+
+ default:
+ append_char (c);
+ break;
+ }
+ } else {
+ _skip--;
+ }
+ _last_char = c;
+ }
+
+ private void append_char (unichar c) {
+ _current_string.append_unichar (c);
+ }
+
+ public virtual int get_line_start_column () {
+ return 0;
+ }
+
+ private SourceLocation get_begin () {
+ return SourceLocation (_last_line, get_line_start_column () + _last_column);
+ }
+
+ private SourceLocation get_end (int offset = 0) {
+ return SourceLocation (_line, get_line_start_column () + _column + offset);
+ }
+
+ private void emit_current_word () throws ParserError {
+ if (_current_string.len > 0) {
+ _parser.accept_token (new Token.from_word (_current_string.str, get_begin (), get_end (-1)));
+ _current_string.erase (0, -1);
+
+ _last_line = _line;
+ _last_column = _column - 1;
+ }
+ }
+
+ private void emit_token (TokenType type) throws ParserError {
+ emit_current_word ();
+
+ _parser.accept_token (new Token.from_type (type, get_begin (), get_end (_skip)));
+
+ _last_line = _line;
+ _last_column = _column;
+ }
+
+ }
--- /dev/null
-using GLib;
-using Gee;
-
+ /* markupreader.vala
+ *
+ * Copyright (C) 2008-2009 Jürg Billeter
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Jürg Billeter <j@bitron.ch>
+ */
+
- private Map<string, string> attributes = new HashMap<string, string> ();
+
+ /**
+ * Simple reader for a subset of XML.
+ */
+ public class Valadoc.MarkupReader : Object {
+ public string filename {
+ private set;
+ get;
+ }
+
+ public string name {
+ private set;
+ get;
+ }
+
+ public string content {
+ private set;
+ get;
+ }
+
+ private MappedFile mapped_file;
+
+ private string[] lines;
+ private char* begin;
+ private char* current;
+ private char* end;
+
+ private int line;
+ private int column;
+
- public Map<string,string> get_attributes () {
- var result = new HashMap<string, string> ();
- foreach (var key in attributes.keys) {
++ private Vala.Map<string, string> attributes = new Vala.HashMap<string, string> (str_hash, str_equal);
+ private bool empty_element;
+
+ private ErrorReporter reporter;
+
+ public MarkupReader.from_string (string filename, string content, ErrorReporter reporter) {
+ this.filename = filename;
+ this.reporter = reporter;
+
+ lines = content.split ("\n");
+ begin = content;
+ end = begin + content.length;
+ current = begin;
+
+ column = 1;
+ line = 1;
+ }
+
+ public MarkupReader (string filename, ErrorReporter reporter) {
+ this.filename = filename;
+ this.reporter = reporter;
+
+ try {
+ mapped_file = new MappedFile (filename, false);
+ begin = mapped_file.get_contents ();
+ lines = ((string) begin).split ("\n");
+ end = begin + mapped_file.get_length ();
+
+ current = begin;
+
+ line = 1;
+ column = 1;
+ } catch (FileError e) {
+ reporter.simple_error (null, "Unable to map file '%s': %s", filename, e.message);
+ }
+ }
+
+ public string? get_line_content (int line_nr) {
+ if (this.lines.length > line_nr) {
+ return this.lines[line_nr];
+ }
+
+ return null;
+ }
+
+ public string? get_attribute (string attr) {
+ return attributes[attr];
+ }
+
+ /*
+ * Returns a copy of the current attributes.
+ *
+ * @return map of current attributes
+ */
++ public Vala.Map<string,string> get_attributes () {
++ var result = new Vala.HashMap<string, string> (str_hash, str_equal);
++ foreach (var key in attributes.get_keys ()) {
+ result.set (key, attributes.get (key));
+ }
+ return result;
+ }
+
+ private string read_name () {
+ char* begin = current;
+ while (current < end) {
+ if (current[0] == ' ' || current[0] == '\t' || current[0] == '>'
+ || current[0] == '/' || current[0] == '=' || current[0] == '\n') {
+ break;
+ }
+ unichar u = ((string) current).get_char_validated ((long) (end - current));
+ if (u != (unichar) (-1)) {
+ current += u.to_utf8 (null);
+ } else {
+ reporter.simple_error ("%s:%d".printf (filename, line),
+ "invalid UTF-8 character");
+ }
+ }
+ if (current == begin) {
+ // syntax error: invalid name
+ }
+ return ((string) begin).substring (0, (int) (current - begin));
+ }
+
+ public MarkupTokenType read_token (out MarkupSourceLocation token_begin, out MarkupSourceLocation token_end) {
+ attributes.clear ();
+
+ if (empty_element) {
+ empty_element = false;
+ token_begin = MarkupSourceLocation (begin, line, column);
+ token_end = MarkupSourceLocation (begin, line, column);
+ return MarkupTokenType.END_ELEMENT;
+ }
+
+ content = null;
+ name = null;
+
+ space ();
+
+ MarkupTokenType type = MarkupTokenType.NONE;
+ char* begin = current;
+ token_begin = MarkupSourceLocation (begin, line, column);
+
+ if (current >= end) {
+ type = MarkupTokenType.EOF;
+ } else if (current[0] == '<') {
+ current++;
+ if (current >= end) {
+ // error
+ } else if (current[0] == '?') {
+ // processing instruction
+ } else if (current[0] == '!') {
+ // comment or doctype
+ current++;
+ if (current < end - 1 && current[0] == '-' && current[1] == '-') {
+ // comment
+ current += 2;
+ while (current < end - 2) {
+ if (current[0] == '-' && current[1] == '-' && current[2] == '>') {
+ // end of comment
+ current += 3;
+ break;
+ } else if (current[0] == '\n') {
+ line++;
+ column = 0;
+ }
+ current++;
+ }
+
+ // ignore comment, read next token
+ return read_token (out token_begin, out token_end);
+ }
+ } else if (current[0] == '/') {
+ type = MarkupTokenType.END_ELEMENT;
+ current++;
+ name = read_name ();
+ if (current >= end || current[0] != '>') {
+ // error
+ }
+ current++;
+ } else {
+ type = MarkupTokenType.START_ELEMENT;
+ name = read_name ();
+ space ();
+ while (current < end && current[0] != '>' && current[0] != '/') {
+ string attr_name = read_name ();
+ if (current >= end || current[0] != '=') {
+ // error
+ }
+ current++;
+ // FIXME allow single quotes
+ if (current >= end || current[0] != '"') {
+ // error
+ }
+ current++;
+
+ string attr_value = text ('"', false);
+
+ if (current >= end || current[0] != '"') {
+ // error
+ }
+ current++;
+ attributes.set (attr_name, attr_value);
+ space ();
+ }
+ if (current[0] == '/') {
+ empty_element = true;
+ current++;
+ space ();
+ } else {
+ empty_element = false;
+ }
+ if (current >= end || current[0] != '>') {
+ // error
+ }
+ current++;
+ }
+ } else {
+ space ();
+
+ if (current[0] != '<') {
+ content = text ('<', true);
+ } else {
+ // no text
+ // read next token
+ return read_token (out token_begin, out token_end);
+ }
+
+ type = MarkupTokenType.TEXT;
+ }
+
+ token_end = MarkupSourceLocation (current, line, column - 1);
+
+ return type;
+ }
+
+ private string text (char end_char, bool rm_trailing_whitespace) {
+ StringBuilder content = new StringBuilder ();
+ char* text_begin = current;
+ char* last_linebreak = current;
+
+ while (current < end && current[0] != end_char) {
+ unichar u = ((string) current).get_char_validated ((long) (end - current));
+ if (u == (unichar) (-1)) {
+ reporter.simple_error ("%s:%d".printf (filename, line),
+ "invalid UTF-8 character");
+ } else if (u == '&') {
+ char* next_pos = current + u.to_utf8 (null);
+ if (((string) next_pos).has_prefix ("amp;")) {
+ content.append (((string) text_begin).substring (0, (int) (current - text_begin)));
+ content.append_c ('&');
+ current += 5;
+ text_begin = current;
+ } else if (((string) next_pos).has_prefix ("quot;")) {
+ content.append (((string) text_begin).substring (0, (int) (current - text_begin)));
+ content.append_c ('"');
+ current += 6;
+ text_begin = current;
+ } else if (((string) next_pos).has_prefix ("apos;")) {
+ content.append (((string) text_begin).substring (0, (int) (current - text_begin)));
+ content.append_c ('\'');
+ current += 6;
+ text_begin = current;
+ } else if (((string) next_pos).has_prefix ("lt;")) {
+ content.append (((string) text_begin).substring (0, (int) (current - text_begin)));
+ content.append_c ('<');
+ current += 4;
+ text_begin = current;
+ } else if (((string) next_pos).has_prefix ("gt;")) {
+ content.append (((string) text_begin).substring (0, (int) (current - text_begin)));
+ content.append_c ('>');
+ current += 4;
+ text_begin = current;
+ } else if (((string) next_pos).has_prefix ("percnt;")) {
+ content.append (((string) text_begin).substring (0, (int) (current - text_begin)));
+ content.append_c ('>');
+ current += 8;
+ text_begin = current;
+ } else {
+ current += u.to_utf8 (null);
+ }
+ } else {
+ if (u == '\n') {
+ line++;
+ column = 0;
+ last_linebreak = current;
+ }
+
+ current += u.to_utf8 (null);
+ column++;
+ }
+ }
+
+ if (text_begin != current) {
+ content.append (((string) text_begin).substring (0, (int) (current - text_begin)));
+ }
+
+ column += (int) (current - last_linebreak);
+
+ // Removes trailing whitespace
+ if (rm_trailing_whitespace) {
+ char* str_pos = ((char*)content.str) + content.len;
+ for (str_pos--; str_pos > ((char*)content.str) && str_pos[0].isspace(); str_pos--);
+ content.erase ((ssize_t) (str_pos-((char*) content.str) + 1), -1);
+ }
+
+ return content.str;
+ }
+
+ private void space () {
+ while (current < end && current[0].isspace ()) {
+ if (current[0] == '\n') {
+ line++;
+ column = 0;
+ }
+ current++;
+ column++;
+ }
+ }
+ }
+
+
--- /dev/null
-using Gee;
-
-
+ /* moduleloader.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Brosch Florian <flo.brosch@gmail.com>
+ */
+
-
-
-
+ [CCode (has_target = false)]
+ public delegate void Valadoc.TagletRegisterFunction (ModuleLoader loader);
+
- private HashMap<string, ModuleData> doclets = new HashMap<string, ModuleData> ();
- private HashMap<string, ModuleData> drivers = new HashMap<string, ModuleData> ();
- private HashMap<string, GLib.Type> taglets = new HashMap<string, GLib.Type> ();
+ public class Valadoc.ModuleLoader : Object {
- // driver path helpers:
++ private Vala.HashMap<string, ModuleData> doclets = new Vala.HashMap<string, ModuleData> (str_hash, str_equal);
++ private Vala.HashMap<string, GLib.Type> taglets = new Vala.HashMap<string, GLib.Type> (str_hash, str_equal);
+
+ private static ModuleLoader instance;
+
+ public static ModuleLoader get_instance () {
+ if (instance == null) {
+ instance = new ModuleLoader ();
+ Taglets.init (instance);
+ }
+ return instance;
+ }
+
+ private ModuleLoader () {
+ }
+
+ private class ModuleData : Object {
+ public Module module;
+ public Type type;
+ }
+
+
+ //
- private struct DriverMetaData {
- public int64[] segments_min;
- public int64[] segments_max;
- public string driver_name;
-
- public DriverMetaData (int64 min_a, int64 min_b, int64 max_a, int64 max_b, string driver_name) {
- this.segments_min = {min_a, min_b};
- this.segments_max = {max_a, max_b};
- this.driver_name = driver_name;
- }
- }
-
- public static bool is_driver (string path) {
- string library_path = Path.build_filename (path, "libdriver." + Module.SUFFIX);
- return FileUtils.test (path, FileTest.EXISTS) && FileUtils.test (library_path, FileTest.EXISTS);
- }
-
++ // path helpers:
+ //
+
- return Path.build_filename (Config.plugin_dir, pluginsubdir, pluginpath);
+ public static bool is_doclet (string path) {
+ string library_path = Path.build_filename (path, "libdoclet." + Module.SUFFIX);
+ return FileUtils.test (path, FileTest.EXISTS) && FileUtils.test (library_path, FileTest.EXISTS);
+ }
+
+ private static string get_plugin_path (string pluginpath, string pluginsubdir) {
+ if (Path.is_absolute (pluginpath) == false) {
+ // Test to see if the plugin exists in the expanded path and then fallback
+ // to using the configured plugin directory
+ string local_path = Path.build_filename (Environment.get_current_dir(), pluginpath);
+ if (is_doclet(local_path)) {
+ return local_path;
+ } else {
- return Path.build_filename (Config.plugin_dir, "doclets", "html");
++ return Path.build_filename (Config.PACKAGE_DATADIR, pluginsubdir, pluginpath);
+ }
+ }
+
+ return pluginpath;
+ }
+
+ public static string get_doclet_path (string? docletpath, ErrorReporter reporter) {
+ if (docletpath == null) {
- public static string? get_driver_path (string? _driverpath, ErrorReporter reporter) {
- string? driverpath = _driverpath;
- // no driver selected
- if (driverpath == null) {
- driverpath = Config.default_driver;
- }
-
-
- // selected string is a plugin directory
- string extended_driver_path = get_plugin_path (driverpath, "drivers");
- if (is_driver (extended_driver_path)) {
- return extended_driver_path;
- }
-
-
- // selected string is a `valac --version` number:
- if (driverpath.has_prefix ("Vala ")) {
- if (driverpath.has_suffix ("-dirty")) {
- driverpath = driverpath.substring (5, driverpath.length - 6 - 5);
- } else {
- driverpath = driverpath.substring (5);
- }
- }
-
- string[] segments = driverpath.split (".");
- if (segments.length != 2 && // e.g. 0.20, --pkg-version
- segments.length != 3 && // e.g. 0.20.3, --version
- segments.length != 4) // e.g. Vala 0.18.0.60-a4cdb, --version
- {
- reporter.simple_error (null, "Invalid driver version format.");
- return null;
- }
-
-
- int64 segment_a;
- int64 segment_b;
- int64 segment_c = 0;
- bool tmp;
-
- tmp = int64.try_parse (segments[0], out segment_a);
- tmp &= int64.try_parse (segments[1], out segment_b);
-
- if (segments.length > 2) {
- tmp &= int64.try_parse (segments[2], out segment_c);
- }
-
- if (!tmp) {
- reporter.simple_error (null, "Invalid driver version format.");
- return null;
- }
-
- DriverMetaData[] lut = {
- DriverMetaData (0, 19, 0, 20, "0.20.x"),
- DriverMetaData (0, 21, 0, 22, "0.22.x"),
- DriverMetaData (0, 23, 0, 24, "0.24.x"),
- DriverMetaData (0, 25, 0, 26, "0.26.x"),
- DriverMetaData (0, 27, 0, 28, "0.28.x"),
- DriverMetaData (0, 29, 0, 30, "0.30.x"),
- DriverMetaData (0, 31, 0, 32, "0.32.x"),
- DriverMetaData (0, 33, 0, 34, "0.34.x"),
- DriverMetaData (0, 35, 0, 36, "0.36.x")
- };
-
-
- for (int i = 0; i < lut.length ; i++) {
- bool frst_seg = lut[i].segments_min[0] <= segment_a && lut[i].segments_max[0] >= segment_a;
- bool scnd_seg = lut[i].segments_min[1] <= segment_b && lut[i].segments_max[1] >= segment_b;
- if (frst_seg && scnd_seg) {
- return Path.build_filename (Config.plugin_dir, "drivers", lut[i].driver_name);
- }
- }
-
-
- reporter.simple_error (null, "No suitable driver found for libvala version " +
- "%" + int64.FORMAT_MODIFIER + "d.%" + int64.FORMAT_MODIFIER + "d.%" + int64.FORMAT_MODIFIER + "d. " +
- "Ensure the selected vala version was installed while building valadoc or use --driver to select another one.",
- segment_a, segment_b, segment_c);
- return null;
- }
-
++ return Path.build_filename (Config.PACKAGE_DATADIR, "doclets", "html");
+ }
+
+ return get_plugin_path (docletpath, "doclets");
+ }
+
- return (taglets.has_key (keyword))? (Content.Taglet) GLib.Object.new (taglets.get (keyword)) : null;
+ //
+ // Creation methods:
+ //
+
+ public Content.Taglet? create_taglet (string keyword) {
-
- public Driver? create_driver (string _path) {
- string path = realpath (_path);
-
- ModuleData? data = drivers.get (path);
- if (data == null) {
- void* function;
-
- Module? module = Module.open (Module.build_path (path, "libdriver"), ModuleFlags.BIND_LAZY | ModuleFlags.BIND_LOCAL);
- if (module == null) {
- return null;
- }
-
- module.symbol("register_plugin", out function);
- if (function == null) {
- return null;
- }
-
- Valadoc.DriverRegisterFunction register_func = (Valadoc.DriverRegisterFunction) function;
- data = new ModuleData ();
- drivers.set (path, data);
-
- data.type = register_func (this);
- data.module = (owned) module;
- }
-
- return (Driver) GLib.Object.new (data.type);
- }
++ return (taglets.contains (keyword))? (Content.Taglet) GLib.Object.new (taglets.get (keyword)) : null;
+ }
+
+ public void register_taglet (string keyword, Type type) {
+ taglets.set (keyword, type);
+ }
+
+ public Doclet? create_doclet (string _path) {
+ string path = realpath (_path);
+
+ ModuleData? data = doclets.get (path);
+ if (data == null) {
+ void* function;
+
+ Module? module = Module.open (Module.build_path (path, "libdoclet"), ModuleFlags.BIND_LAZY | ModuleFlags.BIND_LOCAL);
+ if (module == null) {
+ return null;
+ }
+
+ module.symbol("register_plugin", out function);
+ if (function == null) {
+ return null;
+ }
+
+ Valadoc.DocletRegisterFunction register_func = (Valadoc.DocletRegisterFunction) function;
+ data = new ModuleData ();
+ doclets.set (path, data);
+
+ data.type = register_func (this);
+ data.module = (owned) module;
+ }
+
+ return (Doclet) GLib.Object.new (data.type);
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* manyrule.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ internal class Valadoc.ManyRule : Rule {
+
+ public ManyRule (Object scheme) {
+ _scheme = scheme;
+ }
+
+ private Object _scheme;
+
+ private class State : Object {
+ public bool started = false;
+ public bool done_one = false;
+ }
+
+ public override bool is_optional () {
+ return is_optional_rule (_scheme);
+ }
+
+ public override bool starts_with_token (Token token) {
+ if (has_start_token (_scheme, token)) {
+ return true;
+ }
+ return false;
+ }
+
+ public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward)
+ throws ParserError
+ {
+ var state = parser.get_rule_state () as State;
+ if (state == null) {
+ state = new State ();
+ parser.set_rule_state (state);
+ }
+
+ if (!state.started) {
+ do_start (parser);
+ state.started = true;
+ }
+
+ if (state.done_one && parser.would_parent_accept_token (token)) {
+ do_reduce (parser);
+ return false;
+ }
+ if (parser.would_parent_reduce_to_rule (token, this)) {
+ do_reduce (parser);
+ return false;
+ }
+
+ bool handled;
+ if (try_to_apply (_scheme, token, parser, out handled)) {
+ state.done_one = true;
+ return handled;
+ }
+ if (parser.would_parent_accept_token (token)) {
+ do_reduce (parser);
+ return false;
+ }
+
+ if (_scheme is TokenType) {
+ parser.error (null, "expected %s".printf (((TokenType) _scheme).to_pretty_string ()));
+ } else {
+ parser.error (token, "unexpected token");
+ }
+ assert_not_reached ();
+ }
+
+ public override bool would_accept_token (Token token, Object? state) {
+ if (has_start_token (_scheme, token)) {
+ return true;
+ }
+ return false;
+ }
+
+ public override bool would_reduce (Token token, Object? rule_state) {
+ var state = rule_state as State;
+ return state.done_one || is_optional_rule (_scheme);
+ }
+
+ public override string to_string (Object? rule_state) {
+ var state = rule_state as State;
+ if (state == null) {
+ state = new State ();
+ }
+ return "%-15s%-15s(started=%s;done_one=%s)".printf (name != null ? name : " ",
+ "[many]",
+ state.started.to_string (),
+ state.done_one.to_string ());
+ }
+ }
--- /dev/null
-using Gee;
+ /* oneofrule.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ internal class Valadoc.OneOfRule : Rule {
+
+ public OneOfRule (Object[] scheme) {
+ _scheme = scheme;
+ }
+
+ private Object[] _scheme;
+
+ private class State : Object {
+ public int selected = -1;
+ }
+
+ public override bool is_optional () {
+ return false;
+ }
+
+ public override bool starts_with_token (Token token) {
+ foreach (Object? scheme_element in _scheme) {
+ if (has_start_token (scheme_element, token)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward)
+ throws ParserError
+ {
+ var state = parser.get_rule_state () as State;
+ if (state == null) {
+ state = new State ();
+ parser.set_rule_state (state);
+ }
+
+ if (state.selected == -1) {
+ do_start (parser);
+
+ bool handled;
+ for (int i = 0; i < _scheme.length; i++) {
+ Object? scheme_element = _scheme[i];
+ if (try_to_apply (scheme_element, token, parser, out handled)) {
+ state.selected = i;
+ return handled;
+ }
+ }
+ } else {
+ do_reduce (parser);
+ return false;
+ }
+
+ parser.error (token, "unexpected token");
+ assert_not_reached ();
+ }
+
+ public override bool would_accept_token (Token token, Object? state) {
+ return false;
+ }
+
+ public override bool would_reduce (Token token, Object? rule_state) {
+ var state = rule_state as State;
+ return state.selected != -1;
+ }
+
+ public override string to_string (Object? rule_state) {
+ var state = rule_state as State;
+ if (state == null) {
+ state = new State ();
+ }
+ return "%-15s%-15s(selected=%d/%d)".printf (name != null ? name : " ",
+ "[one-of]",
+ state.selected,
+ _scheme.length);
+ }
+ }
--- /dev/null
-using Gee;
+ /* optionalrule.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ internal class Valadoc.OptionalRule : Rule {
+
+ public OptionalRule (Object scheme) {
+ _scheme = scheme;
+ }
+
+ private Object _scheme;
+
+ private class State : Object {
+ public bool started = false;
+ }
+
+ public override bool is_optional () {
+ return true;
+ }
+
+ public override bool starts_with_token (Token token) {
+ return has_start_token (_scheme, token);
+ }
+
+ public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward)
+ throws ParserError
+ {
+ var state = parser.get_rule_state () as State;
+ if (state == null) {
+ state = new State ();
+ parser.set_rule_state (state);
+ }
+
+ if (!state.started) {
+ do_start (parser);
+ state.started = true;
+
+ bool handled;
+ if (try_to_apply (_scheme, token, parser, out handled)) {
+ return handled;
+ } else {
+ do_skip (parser);
+ return false;
+ }
+ } else {
+ do_reduce (parser);
+ return false;
+ }
+ }
+
+ public override bool would_accept_token (Token token, Object? state) {
+ return false;
+ }
+
+ public override bool would_reduce (Token token, Object? state) {
+ return true;
+ }
+
+ public override string to_string (Object? rule_state) {
+ var state = rule_state as State;
+ if (state == null) {
+ state = new State ();
+ }
+ return "%-15s%-15s(started=%s)".printf (name != null ? name : " ",
+ "[option]",
+ state.started.to_string ());
+ }
+ }
--- /dev/null
-using Gee;
+ /* parser.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- private ArrayList<Rule> rule_stack = new ArrayList<Rule> ();
- private ArrayList<Object?> rule_state_stack = new ArrayList<Object?> ();
+
+ public errordomain Valadoc.ParserError {
+ INTERNAL_ERROR,
+ UNEXPECTED_TOKEN
+ }
+
+ public class Valadoc.Parser : ParserCallback {
+
+ public Parser (Settings settings, Scanner scanner, ErrorReporter reporter) {
+ _settings = settings;
+ _scanner = scanner;
+ _reporter = reporter;
+
+ TokenType.init_token_types ();
+ }
+
+ private Settings _settings;
+ private Scanner _scanner;
+ private ErrorReporter _reporter;
+ private Rule _root_rule;
+
+ private string _filename;
+ private int _first_line;
+ private int _first_column;
+ private Token _current_token;
+
++ private Vala.ArrayList<Rule> rule_stack = new Vala.ArrayList<Rule> ();
++ private Vala.ArrayList<Object?> rule_state_stack = new Vala.ArrayList<Object?> ();
+
+ public void set_root_rule (Rule root_rule) {
+ _root_rule = root_rule;
+ }
+
+ public void parse (string content, string filename, int first_line, int first_column)
+ throws ParserError
+ {
+ _filename = filename;
+ _first_line = first_line;
+ _first_column = first_column;
+
+ rule_stack.clear ();
+ rule_state_stack.clear ();
+
+ try {
+ push_rule (_root_rule);
+ _scanner.reset ();
+ _scanner.scan (content);
+ _scanner.end ();
+
+ if (rule_stack.size != 0) {
+ error (null, "Rule stack is not empty!");
+ }
+ } catch (ParserError e) {
+ #if DEBUG
+ log_error (e.message);
+ #endif
+ // Set an in_error boolean, try to recover
+ // And only throw the error at the end of parse ?
+ throw e;
+ }
+ }
+
+ public void accept_token (Token token) throws ParserError {
+ #if HARD_DEBUG
+ debug ("Incomming token: %s", token.to_pretty_string ());
+ #endif
+
+ _current_token = token;
+ int rule_depth = rule_stack.size;
+ Rule.Forward forward = Rule.Forward.NONE;
+ Rule? rule = peek_rule ();
+ if (rule == null) {
+ throw new ParserError.INTERNAL_ERROR ("Rule stack is empty!");
+ }
+ while (rule != null) {
+ if (rule.accept_token (token, this, forward)) {
+ break;
+ }
+
+ // Check for invalid recursion
+ if (rule_depth != rule_stack.size && peek_rule () == rule) {
+ error (null, "Parser state error");
+ break;
+ }
+ rule = peek_rule ();
+
+ // Rule stack size have changed
+ // Check for propagation
+ forward = rule_depth > rule_stack.size ? Rule.Forward.CHILD
+ : Rule.Forward.PARENT;
+ rule_depth = rule_stack.size;
+ }
+ }
+
+ private Rule? peek_rule (int offset = -1) {
+ assert (offset < 0);
+ if (rule_stack.size + offset < 0) {
+ return null;
+ }
+ return rule_stack.get (rule_stack.size + offset);
+ }
+
+ private Rule pop_rule () {
+ int last_index = rule_stack.size - 1;
+ Rule rule = rule_stack.get (last_index);
+ rule_stack.remove_at (last_index);
+ rule_state_stack.remove_at (last_index);
+ return rule;
+ }
+
+ public void push_rule (Rule rule) {
+ rule_stack.add (rule);
+ rule_state_stack.add (null);
+
+ #if HARD_DEBUG
+ debug ("Pushed at %2d: %s", rule_stack.size - 1, rule.to_string (null));
+ #endif
+ }
+
+ private Object? peek_state (int offset = -1) {
+ assert (offset < 0);
+ if (rule_state_stack.size + offset < 0) {
+ return null;
+ }
+ return rule_state_stack.get (rule_state_stack.size + offset);
+ }
+
+ public Object? get_rule_state () {
+ return peek_state ();
+ }
+
+ public void set_rule_state (Object state) {
+ int last_index = rule_stack.size - 1;
+ rule_state_stack.set (last_index, state);
+ }
+
+ public void reduce () {
+ pop_rule ();
+
+ #if HARD_DEBUG
+ Rule? parent_rule = peek_rule ();
+ if (parent_rule != null) {
+ debug ("Reduced to %2d: %s", rule_stack.size - 1,
+ parent_rule.to_string (peek_state ()));
+ }
+ #endif
+ }
+
+ public bool would_parent_accept_token (Token token) {
+ int offset = -2;
+ Rule? parent_rule = peek_rule (offset);
+ Object? state = peek_state (offset);
+ while (parent_rule != null) {
+ #if VERY_HARD_DEBUG
+ debug ("WouldAccept - Offset %d; Index %d: %s", offset,
+ rule_stack.size + offset, parent_rule.to_string (state));
+ #endif
+ if (parent_rule.would_accept_token (token, state)) {
+ #if VERY_HARD_DEBUG
+ debug ("WouldAccept - Yes");
+ #endif
+ return true;
+ }
+ if (!parent_rule.would_reduce (token, state)) {
+ #if VERY_HARD_DEBUG
+ debug ("WouldAccept - No");
+ #endif
+ return false;
+ }
+ offset--;
+ parent_rule = peek_rule (offset);
+ state = peek_state (offset);
+ }
+ #if VERY_HARD_DEBUG
+ debug ("WouldAccept - No");
+ #endif
+ return false;
+ }
+
+ public bool would_parent_reduce_to_rule (Token token, Rule rule) {
+ int offset = -2;
+ Rule? parent_rule = peek_rule (offset);
+ Object? state = peek_state (offset);
+ while (parent_rule != null) {
+ #if VERY_HARD_DEBUG
+ debug ("WouldReduce - Offset %d; Index %d: %s", offset,
+ rule_stack.size + offset, parent_rule.to_string (state));
+ #endif
+ if (!parent_rule.would_reduce (token, state)) {
+ break;
+ }
+ offset--;
+ parent_rule = peek_rule (offset);
+ state = peek_state (offset);
+ }
+ if ((parent_rule != null && parent_rule.would_accept_token (token, state))
+ || (parent_rule == null && TokenType.EOF.matches (token))) {
+ #if VERY_HARD_DEBUG
+ debug ("WouldReduce - Yes");
+ #endif
+ return true;
+ }
+ #if VERY_HARD_DEBUG
+ debug ("WouldReduce - No");
+ #endif
+ return false;
+ }
+
+ public void warning (Token? token, string message) {
+ string error_message;
+
+ if (token != null) {
+ error_message = message + ": " + token.to_pretty_string ();
+ } else {
+ error_message = message;
+ }
+
+ _reporter.warning (_filename,
+ get_line (token),
+ get_start_column (token),
+ get_end_column (token),
+ _scanner.get_line_content (),
+ error_message);
+ }
+
+ public void error (Token? token, string message) throws ParserError {
+ string error_message;
+
+ if (token != null) {
+ error_message = message + ": " + token.to_pretty_string ();
+ } else {
+ error_message = message;
+ }
+
+ _reporter.error (_filename,
+ get_line (token),
+ get_start_column (token),
+ get_end_column (token),
+ _scanner.get_line_content (),
+ error_message);
+
+ throw new ParserError.UNEXPECTED_TOKEN (error_message);
+ }
+
+ private int get_line (Token? token) {
+ if (token == null) {
+ token = _current_token;
+ }
+ return token.begin.line + _first_line;
+ }
+
+ private int get_start_column (Token? token) {
+ if (token == null) {
+ token = _current_token;
+ }
+ if (token.begin.line == 0) {
+ return token.begin.column + _first_column + 1;
+ } else {
+ return token.begin.column + 1;
+ }
+ }
+
+ private int get_end_column (Token? token) {
+ if (token == null) {
+ token = _current_token;
+ }
+ if (token.end.line == 0) {
+ return token.end.column + _first_column + 1;
+ } else {
+ return token.end.column + 1;
+ }
+ }
+
+ #if DEBUG
+ private void log_error (string message) {
+ stderr.printf ("An error occured while parsing: %s\n", message);
+ stderr.printf ("\nDumping rule stack:\n");
+ for (int i = 0; i < rule_stack.size; i++) {
+ stderr.printf ("\t%2d: %s\n", i, rule_stack[i].to_string (rule_state_stack[i]));
+ }
+ }
+ #endif
+ }
--- /dev/null
-using Gee;
+ /* parsercallback.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public interface Valadoc.ParserCallback {
+ public abstract Object? get_rule_state ();
+ public abstract void set_rule_state (Object state);
+
+ public abstract void push_rule (Rule rule);
+ public abstract void reduce ();
+
+ public abstract bool would_parent_accept_token (Token token);
+ public abstract bool would_parent_reduce_to_rule (Token token, Rule rule);
+
+ public abstract void warning (Token? token, string message);
+ public abstract void error (Token? token, string message) throws ParserError;
+ }
--- /dev/null
-using Gee;
+ /* rule.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public abstract class Valadoc.Rule : Object {
+
+ public static Rule seq (Object[] scheme) {
+ return new SequenceRule (scheme);
+ }
+
+ public static Rule one_of (Object[] scheme) {
+ return new OneOfRule (scheme);
+ }
+
+ public static Rule many (Object[] scheme) {
+ if (scheme.length == 1) {
+ return new ManyRule (scheme[0]);
+ } else {
+ return new ManyRule (new SequenceRule (scheme));
+ }
+ }
+
+ public static Rule option (Object[] scheme) {
+ if (scheme.length == 1) {
+ return new OptionalRule (scheme[0]);
+ } else {
+ return new OptionalRule (new SequenceRule (scheme));
+ }
+ }
+
+ protected Rule () {
+ }
+
+ private string? _name = null;
+ private Action _start_action;
+ private Action _reduce_action;
+ private Action _skip_action;
+
+ public string name { get { return _name; } }
+
+ public Rule set_name (string name) {
+ _name = name;
+ return this;
+ }
+
+ public delegate void Action () throws ParserError;
+
+ public Rule set_start (Action action) {
+ //TODO: Ownership Transfer
+ _start_action = () => { action (); };
+ return this;
+ }
+
+ public Rule set_reduce (Action action) {
+ //TODO: Ownership Transfer
+ _reduce_action = () => { action (); };
+ return this;
+ }
+
+ public Rule set_skip (Action action) {
+ //TODO: Ownership Transfer
+ _skip_action = () => { action (); };
+ return this;
+ }
+
+ public enum Forward {
+ NONE,
+ PARENT,
+ CHILD
+ }
+
+ public abstract bool is_optional ();
+ public abstract bool starts_with_token (Token token);
+ public abstract bool accept_token (Token token, ParserCallback parser, Rule.Forward forward) throws ParserError;
+ public abstract bool would_accept_token (Token token, Object? state);
+ public abstract bool would_reduce (Token token, Object? state);
+
+ public abstract string to_string (Object? state);
+
+ protected bool is_optional_rule (Object? scheme_element) {
+ Rule? scheme_rule = scheme_element as Rule;
+ if (scheme_rule != null) {
+ return scheme_rule.is_optional ();
+ }
+ return false;
+ }
+
+ protected bool has_start_token (Object? scheme_element, Token token) {
+ TokenType? scheme_token_type = scheme_element as TokenType;
+ if (scheme_token_type != null) {
+ return scheme_token_type.matches (token);
+ }
+ Rule? scheme_rule = scheme_element as Rule;
+ if (scheme_rule != null) {
+ return scheme_rule.starts_with_token (token);
+ }
+ return false;
+ }
+
+ protected bool try_to_apply (Object? scheme_element, Token token, ParserCallback parser,
+ out bool handled) throws ParserError
+ {
+ #if VERY_HARD_DEBUG
+ {
+ TokenType? scheme_token = scheme_element as TokenType;
+ Rule? scheme_rule = scheme_element as Rule;
+ if (scheme_token != null) {
+ message ("TryToApply: token='%s'; scheme_token='%s'", token.to_string (),
+ scheme_token.to_string ());
+ } else if (scheme_rule != null) {
+ message ("TryToApply: token='%s'; scheme_rule='%s'", token.to_string (),
+ scheme_rule.to_string (parser.get_rule_state ()));
+ } else {
+ assert (scheme_element != null);
+ }
+ }
+ #endif
+ TokenType? scheme_token_type = scheme_element as TokenType;
+ if (scheme_token_type != null && scheme_token_type.matches (token)) {
+ scheme_token_type.do_action (token);
+ handled = true;
+ return true;
+ }
+ Rule? scheme_rule = scheme_element as Rule;
+ if (scheme_rule != null && scheme_rule.starts_with_token (token)) {
+ parser.push_rule (scheme_rule);
+ handled = false;
+ return true;
+ }
+
+ handled = false;
+ return false;
+ }
+
+ protected void do_start (ParserCallback parser) throws ParserError {
+ if (_start_action != null) {
+ _start_action ();
+ }
+ }
+
+ protected void do_reduce (ParserCallback parser) throws ParserError {
+ if (_reduce_action != null) {
+ _reduce_action ();
+ }
+ parser.reduce ();
+ }
+
+ protected void do_skip (ParserCallback parser) throws ParserError {
+ if (_skip_action != null) {
+ _skip_action ();
+ }
+ }
+ }
--- /dev/null
+ /* scanner.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
++
+ public interface Valadoc.Scanner : Object {
+
+ public abstract void set_parser (Parser parser);
+
+ public abstract void reset ();
+
+ public abstract void scan (string content) throws ParserError;
+
+ public abstract void end () throws ParserError;
+
+ public abstract void stop ();
+
+ public abstract string get_line_content ();
+ }
--- /dev/null
-using Gee;
+ /* sequencerule.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ internal class Valadoc.SequenceRule : Rule {
+
+ public SequenceRule (Object[] scheme) {
+ _scheme = scheme;
+ }
+
+ private Object[] _scheme;
+
+ private class State : Object {
+ public int index = 0;
+ }
+
+ public override bool is_optional () {
+ return false;
+ }
+
+ public override bool starts_with_token (Token token) {
+ return test_token (0, token);
+ }
+
+ private bool test_token (int from_index, Token token) {
+ int i = from_index;
+ while (i < _scheme.length) {
+ if (has_start_token (_scheme[i], token)) {
+ return true;
+ }
+ if (!is_optional_rule (_scheme[i])) {
+ break;
+ }
+ i++;
+ }
+ return false;
+ }
+
+ private bool test_reduce (int from_index, Token token) {
+ int i = from_index;
+ while (i < _scheme.length) {
+ if (!is_optional_rule (_scheme[i])) {
+ return false;
+ }
+ i++;
+ }
+ return true;
+ }
+
+ public override bool accept_token (Token token, ParserCallback parser,
+ Rule.Forward forward) throws ParserError
+ {
+ var state = parser.get_rule_state () as State;
+ if (state == null) {
+ state = new State ();
+ parser.set_rule_state (state);
+ }
+
+ if (state.index == 0) {
+ do_start (parser);
+ } else if (state.index == _scheme.length) {
+ do_reduce (parser);
+ return false;
+ }
+
+ Object? scheme_element = null;
+ bool handled;
+ do {
+ scheme_element = _scheme[state.index];
+ if (try_to_apply (scheme_element, token, parser, out handled)) {
+ state.index++;
+ return handled;
+ }
+ if (!is_optional_rule (scheme_element)) {
+ break;
+ } else {
+ ((Rule) scheme_element).do_skip (parser);
+ }
+ state.index++;
+ } while (state.index < _scheme.length);
+
+ if (state.index == _scheme.length) {
+ do_reduce (parser);
+ return false;
+ }
+
+ if (scheme_element is TokenType) {
+ parser.error (token, "expected %s".printf (((TokenType) scheme_element).to_pretty_string ()));
+ } else {
+ parser.error (token, "unexpected token");
+ }
+ assert_not_reached ();
+ }
+
+ public override bool would_accept_token (Token token, Object? rule_state) {
+ var state = rule_state as State;
+ return test_token (state.index, token);
+ }
+
+ public override bool would_reduce (Token token, Object? rule_state) {
+ var state = rule_state as State;
+ return state.index == _scheme.length || test_reduce (state.index, token);
+ }
+
+ public override string to_string (Object? rule_state) {
+ var state = rule_state as State;
+ if (state == null) {
+ state = new State ();
+ }
+ return "%-15s%-15s(index=%d/%d)".printf (name != null ? name : " ", "[seq]", state.index, _scheme.length);
+ }
+ }
--- /dev/null
-using Gee;
+ /* stubrule.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.StubRule : Rule {
+
+ public StubRule () {
+ }
+
+ private Rule _rule;
+
+ public Rule set_rule (Rule rule) {
+ _rule = rule;
+ return this;
+ }
+
+ public override bool is_optional () {
+ return _rule.is_optional ();
+ }
+
+ public override bool starts_with_token (Token token) {
+ return _rule.starts_with_token (token);
+ }
+
+ public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward)
+ throws ParserError
+ {
+ return _rule.accept_token (token, parser, forward);
+ }
+
+ public override bool would_accept_token (Token token, Object? state) {
+ return _rule.would_accept_token (token, state);
+ }
+
+ public override bool would_reduce (Token token, Object? state) {
+ return _rule.would_reduce (token, state);
+ }
+
+ public override string to_string (Object? state) {
+ return _rule.to_string (state);
+ }
+ }
--- /dev/null
-using Gee;
+ /* token.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.Token : Object {
+
+ public Token.from_type (TokenType type, SourceLocation begin, SourceLocation end, string? val = null) {
+ _type = type;
+ _begin = begin;
+ _end = end;
+ _value = val;
+ }
+
+ public Token.from_word (string word, SourceLocation begin, SourceLocation end) {
+ _word = word;
+ _begin = begin;
+ _end = end;
+ }
+
+ private TokenType? _type = null;
+ private string? _word = null;
+ private SourceLocation _begin;
+ private SourceLocation _end;
+ private string? _value;
+
+ public bool is_word {
+ get {
+ return _word != null;
+ }
+ }
+
+ public bool is_number {
+ get {
+ if (_word == null || _word.length == 0) {
+ return false;
+ } else if (_word[0] == '0' && _word.length > 1) {
+ return false;
+ }
+ for (int i = 0; i < _word.length; i++) {
+ if (_word[i] < '0' || _word[i] > '9') {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ public string? word {
+ get {
+ return _word;
+ }
+ }
+
+ public string? value {
+ get {
+ return _value;
+ }
+ }
+
+ public TokenType? token_type {
+ get {
+ return _type;
+ }
+ }
+
+ public SourceLocation begin {
+ get {
+ return _begin;
+ }
+ }
+
+ public SourceLocation end {
+ get {
+ return _end;
+ }
+ }
+
+ public string to_string () {
+ return _word == null ? _type.to_string () : _word;
+ }
+
+ public string to_pretty_string () {
+ return _word == null ? _type.to_pretty_string () : _word;
+ }
+
+ public int to_int () {
+ assert (is_number);
+ return int.parse (_word);
+ }
+ }
--- /dev/null
-using Gee;
+ /* tokentype.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
+ public class Valadoc.TokenType : Object {
+ // valadoc-comments:
+ public static TokenType ANY;
+ public static TokenType ANY_WORD;
+ public static TokenType ANY_NUMBER;
+ public static TokenType EOF;
+ public static TokenType EOL;
+ public static TokenType BREAK;
+ public static TokenType AROBASE;
+ public static TokenType SPACE;
+ public static TokenType TAB;
+ public static TokenType EQUAL_1;
+ public static TokenType EQUAL_2;
+ public static TokenType EQUAL_3;
+ public static TokenType EQUAL_4;
+ public static TokenType EQUAL_5;
+ public static TokenType MINUS;
+ public static TokenType LESS_THAN;
+ public static TokenType GREATER_THAN;
+ public static TokenType ALIGN_TOP;
+ public static TokenType ALIGN_BOTTOM;
+ public static TokenType SINGLE_QUOTE_2;
+ public static TokenType SLASH_2;
+ public static TokenType UNDERSCORE_2;
+ public static TokenType BACK_QUOTE_2;
+ public static TokenType OPEN_BRACE;
+ public static TokenType CLOSED_BRACE;
+ public static TokenType DOUBLE_OPEN_BRACE;
+ public static TokenType DOUBLE_CLOSED_BRACE;
+ public static TokenType TRIPLE_OPEN_BRACE;
+ public static TokenType TRIPLE_CLOSED_BRACE;
+ public static TokenType DOUBLE_OPEN_BRACKET;
+ public static TokenType DOUBLE_CLOSED_BRACKET;
+ public static TokenType PIPE;
+ public static TokenType DOUBLE_PIPE;
+ public static TokenType ALIGN_RIGHT;
+ public static TokenType ALIGN_CENTER;
+
+
+ // .valadoc (importer)
+ public static TokenType VALADOC_COMMENT_START;
+ public static TokenType VALADOC_COMMENT_END;
+ public static TokenType VALADOC_ANY_WORD;
+ public static TokenType VALADOC_SPACE;
+ public static TokenType VALADOC_TAB;
+ public static TokenType VALADOC_EOL;
+
+
+ // markdown:
+ public static TokenType MARKDOWN_PARAGRAPH;
+ public static TokenType MARKDOWN_ANY_WORD;
+ public static TokenType MARKDOWN_SPACE;
+ public static TokenType MARKDOWN_SOURCE;
+ public static TokenType MARKDOWN_PARAMETER;
+ public static TokenType MARKDOWN_CONSTANT;
+ public static TokenType MARKDOWN_SYMBOL;
+ public static TokenType MARKDOWN_LOCAL_GMEMBER;
+ public static TokenType MARKDOWN_FUNCTION;
+ public static TokenType MARKDOWN_MAIL;
+ public static TokenType MARKDOWN_LINK;
+ public static TokenType MARKDOWN_GREATER_THAN;
+ public static TokenType MARKDOWN_LESS_THAN;
+ public static TokenType MARKDOWN_OPEN_BRACKET;
+ public static TokenType MARKDOWN_CLOSE_BRACKET;
+ public static TokenType MARKDOWN_OPEN_PARENS;
+ public static TokenType MARKDOWN_CLOSE_PARENS;
+ public static TokenType MARKDOWN_EXCLAMATION_MARK;
+ public static TokenType MARKDOWN_HEADLINE_1;
+ public static TokenType MARKDOWN_HEADLINE_2;
+ public static TokenType MARKDOWN_HEADLINE_HASH;
+ public static TokenType MARKDOWN_HEADLINE_END;
+ public static TokenType MARKDOWN_UNORDERED_LIST_ITEM_START;
+ public static TokenType MARKDOWN_UNORDERED_LIST_ITEM_END;
+ public static TokenType MARKDOWN_ORDERED_LIST_ITEM_START;
+ public static TokenType MARKDOWN_ORDERED_LIST_ITEM_END;
+ public static TokenType MARKDOWN_BLOCK_START;
+ public static TokenType MARKDOWN_BLOCK_END;
+ public static TokenType MARKDOWN_EOC;
+
+
+ private static bool initialized = false;
+
+ internal static void init_token_types () {
+ if (!initialized) {
+ // valadoc-comments:
+ ANY = new TokenType.basic ("<any>");
+ ANY_WORD = new TokenType.basic ("<any-word>");
+ ANY_NUMBER = new TokenType.basic ("<any-number>");
+ EOF = new TokenType.basic ("\0", "<end-of-file>");
+ EOL = new TokenType.basic ("\n", "<end-of-line>");
+ BREAK = new TokenType.basic ("<<BR>>");
+ AROBASE = new TokenType.basic ("@");
+ SPACE = new TokenType.basic (" ", "<space>");
+ TAB = new TokenType.basic ("\t", "<tab>");
+ EQUAL_1 = new TokenType.basic ("=");
+ EQUAL_2 = new TokenType.basic ("==");
+ EQUAL_3 = new TokenType.basic ("====");
+ EQUAL_4 = new TokenType.basic ("=====");
+ EQUAL_5 = new TokenType.basic ("======");
+ MINUS = new TokenType.basic ("-");
+ LESS_THAN = new TokenType.basic ("<");
+ GREATER_THAN = new TokenType.basic (">");
+ ALIGN_TOP = new TokenType.basic ("^");
+ ALIGN_BOTTOM = new TokenType.basic ("v");
+ SINGLE_QUOTE_2 = new TokenType.basic ("''");
+ SLASH_2 = new TokenType.basic ("//");
+ UNDERSCORE_2 = new TokenType.basic ("__");
+ BACK_QUOTE_2 = new TokenType.basic ("``");
+ OPEN_BRACE = new TokenType.basic ("{");
+ CLOSED_BRACE = new TokenType.basic ("}");
+ DOUBLE_OPEN_BRACE = new TokenType.basic ("{{");
+ DOUBLE_CLOSED_BRACE = new TokenType.basic ("}}");
+ TRIPLE_OPEN_BRACE = new TokenType.basic ("{{{");
+ TRIPLE_CLOSED_BRACE = new TokenType.basic ("}}}");
+ DOUBLE_OPEN_BRACKET = new TokenType.basic ("[[");
+ DOUBLE_CLOSED_BRACKET = new TokenType.basic ("]]");
+ PIPE = new TokenType.basic ("|");
+ DOUBLE_PIPE = new TokenType.basic ("||");
+ ALIGN_RIGHT = new TokenType.basic ("))");
+ ALIGN_CENTER = new TokenType.basic (")(");
+
+ // .valadoc (importer)
+ VALADOC_COMMENT_START = new TokenType.basic ("/*");
+ VALADOC_COMMENT_END = new TokenType.basic ("*/");
+ VALADOC_ANY_WORD = ANY_WORD;
+ VALADOC_SPACE = SPACE;
+ VALADOC_TAB = TAB;
+ VALADOC_EOL = EOL;
+
+ initialized = true;
+
+
+ // Markdown: (importer)
+ MARKDOWN_PARAGRAPH = new TokenType.basic ("<paragraph>");
+ MARKDOWN_BLOCK_START = new TokenType.basic ("<block>");
+ MARKDOWN_BLOCK_END = new TokenType.basic ("</block>");
+ MARKDOWN_UNORDERED_LIST_ITEM_START = new TokenType.basic ("<unordered-list>");
+ MARKDOWN_UNORDERED_LIST_ITEM_END = new TokenType.basic ("</unordered-list>");
+ MARKDOWN_ORDERED_LIST_ITEM_START = new TokenType.basic ("<ordered-list>");
+ MARKDOWN_ORDERED_LIST_ITEM_END = new TokenType.basic ("</ordered-list>");
+
+ MARKDOWN_HEADLINE_1 = new TokenType.basic ("<headline-1>");
+ MARKDOWN_HEADLINE_2 = new TokenType.basic ("<headline-2>");
+ MARKDOWN_HEADLINE_HASH = new TokenType.basic ("<hash>");
+ MARKDOWN_HEADLINE_END = new TokenType.basic ("</headline>");
+ MARKDOWN_SOURCE = new TokenType.basic ("<source>");
+ MARKDOWN_PARAMETER = new TokenType.basic ("<parameter>");
+ MARKDOWN_CONSTANT = new TokenType.basic ("<constant>");
+ MARKDOWN_FUNCTION = new TokenType.basic ("<function>");
+ MARKDOWN_SYMBOL = new TokenType.basic ("<symbol>");
+ MARKDOWN_LOCAL_GMEMBER = new TokenType.basic ("<local-gmember>");
+ MARKDOWN_MAIL = new TokenType.basic ("<mail>");
+ MARKDOWN_LINK = new TokenType.basic ("<link>");
+
+ MARKDOWN_OPEN_BRACKET = new TokenType.basic ("[");
+ MARKDOWN_CLOSE_BRACKET = new TokenType.basic ("]");
+ MARKDOWN_OPEN_PARENS = new TokenType.basic ("(");
+ MARKDOWN_CLOSE_PARENS = new TokenType.basic (")");
+ MARKDOWN_EXCLAMATION_MARK = new TokenType.basic ("!");
+ MARKDOWN_GREATER_THAN = GREATER_THAN;
+ MARKDOWN_LESS_THAN = LESS_THAN;
+
+ MARKDOWN_ANY_WORD = ANY_WORD;
+ MARKDOWN_SPACE = SPACE;
+ MARKDOWN_EOC = EOL;
+ }
+ }
+
+ private static int EXACT_WORD = -1;
+
+ public static TokenType str (string str) {
+ return new TokenType (str, EXACT_WORD, null);
+ }
+
+ public static TokenType any () {
+ return ANY;
+ }
+
+ public static TokenType any_word () {
+ return ANY_WORD;
+ }
+
+ public static TokenType any_number () {
+ return ANY_NUMBER;
+ }
+
+ private TokenType (string string_value, int basic_value, Action? __action) {
+ _string_value = string_value;
+ _basic_value = basic_value;
+ if (__action != null) {
+ _action = (token) => { __action (token); };
+ } else {
+ _action = null;
+ }
+ }
+
+ private TokenType.basic (string string_value, string? pretty_string = null) {
+ _string_value = string_value;
+ _pretty_string = pretty_string;
+ _basic_value = ++_last_basic_value;
+ }
+
+ private static int _last_basic_value = -1;
+
+ private string _string_value;
+ private string? _pretty_string;
+ private int _basic_value = -1;
+ private Action? _action = null;
+
+ public delegate void Action (Token token) throws ParserError;
+
+ public TokenType action (Action action) {
+ return new TokenType (_string_value, _basic_value, action);
+ }
+
+ public void do_action (Token matched_token) throws ParserError {
+ if (_action != null) {
+ _action (matched_token);
+ }
+ }
+
+ public bool matches (Token token) {
+ if (_basic_value == ANY._basic_value) {
+ return true;
+ } else if (_basic_value == ANY_WORD._basic_value && token.is_word) {
+ return true;
+ } else if (_basic_value == ANY_NUMBER._basic_value && token.is_number) {
+ return true;
+ } else if (_basic_value == EXACT_WORD && token.is_word && token.word == _string_value) {
+ return true;
+ } else if (token.token_type != null && token.token_type._basic_value == _basic_value) {
+ return true;
+ }
+ return false;
+ }
+
+ public string to_string () {
+ return _string_value;
+ }
+
+ public string to_pretty_string () {
+ if (_pretty_string != null) {
+ return _pretty_string;
+ }
+ return _string_value;
+ }
+ }
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* tagletdeprecated.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
++using Valadoc.Content;
+
+ public class Valadoc.Taglets.Deprecated : BlockContent, Taglet, Block {
+ public Rule? get_parser_rule (Rule run_rule) {
+ return run_rule;
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ base.check (api_root, container, file_path, reporter, settings);
+ reporter.simple_warning ("%s: %s: @deprecated".printf (file_path, container.get_full_name ()),
+ "@deprecated is deprecated. Use [Version (deprecated = true)]");
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_taglet (this);
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Deprecated deprecated = new Deprecated ();
+ deprecated.parent = new_parent;
+
+ foreach (Block element in content) {
+ Block copy = element.copy (deprecated) as Block;
+ deprecated.content.add (copy);
+ }
+
+ return deprecated;
+ }
+ }
+
--- /dev/null
-using Gee;
+ /* tagletinheritdoc.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- Gee.List<Inline> parent_content = null;
++
+ using Valadoc.Content;
+
+ public class Valadoc.Taglets.InheritDoc : InlineTaglet {
+ private Taglet? parent_taglet = null;
+
+ public Api.Node? inherited {
+ private set;
+ get;
+ }
+
+
+ public override Rule? get_parser_rule (Rule run_rule) {
+ return null;
+ }
+
+ private Taglet? find_parent_taglet () {
+ if (_inherited == null || _inherited.documentation == null) {
+ return null;
+ }
+
+ ContentElement pos;
+ for (pos = this.parent; pos != null && pos is Taglet == false; pos = pos.parent);
+ if (pos is Taglet) {
+ return (Taglet) pos;
+ }
+
+ return null;
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // TODO Check that the container is an override of an abstract symbol
+ // Also retrieve that abstract symbol _inherited
+
+ if (container is Api.Method) {
+ _inherited = ((Api.Method) container).base_method;
+ } else if (container is Api.Property) {
+ _inherited = ((Api.Property) container).base_property;
+ } else if (container is Api.Class && ((Api.Class) container).base_type != null) {
+ _inherited = (Api.Node) ((Api.Class) container).base_type.data_type;
+ } else if (container is Api.Struct && ((Api.Struct) container).base_type != null) {
+ _inherited = (Api.Node) ((Api.Struct) container).base_type.data_type;
+ }
+
+ parent_taglet = find_parent_taglet ();
+ if (parent_taglet == null && _inherited != null) {
+ api_root.register_inheritdoc (container, this);
+ }
+
+
+ // TODO report error if inherited is null
+
+ // TODO postpone check after complete parse of the api tree comments
+ // And reenable that check
+ //base.check (api_root, container, reporter);
+ }
+
+ private Run[]? split_run (Inline? separator) {
+ if (separator == null) {
+ return null;
+ }
+
+ ContentElement parent = separator.parent;
- private Run content_copy (Gee.List<ContentElement>? content) {
++ Vala.List<Inline> parent_content = null;
+
+ if (parent is Run && ((Run) parent).style == Run.Style.NONE) {
+ parent_content = ((Run) parent).content;
+ } else if (parent is Paragraph) {
+ parent_content = ((Paragraph) parent).content;
+ }
+
+ if (parent_content != null) {
+ Run right_run = new Run (Run.Style.NONE);
+ Run left_run = new Run (Run.Style.NONE);
+ bool separated = false;
+
+ foreach (var current in parent_content) {
+ if (current == separator) {
+ separated = true;
+ } else if (separated) {
+ right_run.content.add (current);
+ current.parent = right_run;
+ } else {
+ left_run.content.add (current);
+ current.parent = left_run;
+ }
+ }
+
+ return { left_run, right_run };
+ }
+
+ return null;
+ }
+
+ internal void transform (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ ContentElement separator = this;
+ Run right_run = null;
+ Run left_run = null;
+ Run[]? parts;
+
+ while ((parts = split_run (separator as Inline)) != null) {
+ if (left_run != null) {
+ parts[0].content.add (left_run);
+ left_run.parent = parts[0];
+ }
+
+ if (right_run != null) {
+ parts[1].content.insert (0, right_run);
+ right_run.parent = parts[1];
+ }
+
+ separator = separator.parent;
+ right_run = parts[1];
+ left_run = parts[0];
+ }
+
+ if (separator is Paragraph == false || separator.parent is Comment == false) {
+ reporter.simple_error ("%s: %s: @inheritDoc".printf (file_path, container.get_full_name ()),
+ "Parent documentation can't be copied to this location.");
+ return ;
+ }
+
+ Comment comment = separator.parent as Comment;
+ assert (comment != null);
+
+ int insert_pos = comment.content.index_of ((Paragraph) separator);
+ int start_pos = insert_pos;
+ assert (insert_pos >= 0);
+
+ foreach (Block block in _inherited.documentation.content) {
+ comment.content.insert (insert_pos, (Block) block.copy (comment));
+ insert_pos++;
+ }
+
+ if (right_run != null) {
+ if (comment.content[insert_pos - 1] is Paragraph) {
+ ((Paragraph) comment.content[insert_pos - 1]).content.add (right_run);
+ right_run.parent = comment.content[insert_pos - 1];
+ } else {
+ Paragraph p = new Paragraph ();
+ p.content.add (right_run);
+ right_run.parent = p;
+ p.parent = comment;
+ comment.content.insert (insert_pos, p);
+ }
+ }
+
+ if (left_run != null) {
+ if (comment.content[start_pos] is Paragraph) {
+ ((Paragraph) comment.content[start_pos]).content.insert (0, left_run);
+ left_run.parent = comment.content[start_pos];
+ } else {
+ Paragraph p = new Paragraph ();
+ p.content.add (left_run);
+ left_run.parent = p;
+ p.parent = comment;
+ comment.content.insert (start_pos, p);
+ }
+ }
+
+ comment.content.remove ((Paragraph) separator);
+ }
+
- Gee.List<Taglet> parent_taglets = _inherited.documentation.find_taglets (null, parent_taglet.get_type ());
++ private Run content_copy (Vala.List<ContentElement>? content) {
+ Run run = new Run (Run.Style.NONE);
+ run.parent = this;
+
+ if (content != null) {
+ foreach (ContentElement item in content) {
+ run.content.add (item.copy (this) as Inline);
+ }
+ }
+
+ return run;
+ }
+
+ public override ContentElement produce_content () {
+ if (_inherited != null && _inherited.documentation != null && parent_taglet != null) {
++ Vala.List<Taglet> parent_taglets = _inherited.documentation.find_taglets (null, parent_taglet.get_type ());
+ foreach (Taglet parent in parent_taglets) {
+ // we only care about the first match:
+ if (parent.inheritable (parent_taglet)) {
+ return content_copy (parent.get_inheritable_documentation ());
+ }
+ }
+ }
+ return new Text ("");
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ InheritDoc doc = new InheritDoc ();
+ doc.parent = new_parent;
+
+ doc.settings = settings;
+ doc.locator = locator;
+
+ doc._inherited = _inherited;
+
+ return doc;
+ }
+ }
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* taglet.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
++using Valadoc.Content;
+
+ public class Valadoc.Taglets.Link : InlineTaglet {
+ public string symbol_name { internal set; get; }
+
+ /**
+ * Accept leading 's', e.g. #Widgets
+ */
+ public bool c_accept_plural { internal set; get; }
+
+ /**
+ * True if symbol_name could only be resolved after removing 's'
+ *
+ * E.g. true or #Widgets, false for #Widget
+ */
+ public bool c_is_plural { private set; get; }
+
+
+ private enum SymbolContext {
+ NORMAL,
+ FINISH,
+ TYPE
+ }
+
+ private SymbolContext _context = SymbolContext.NORMAL;
+ private Api.Node _symbol;
+
+ public override Rule? get_parser_rule (Rule run_rule) {
+ return Rule.seq ({
+ Rule.option ({ Rule.many ({ TokenType.SPACE }) }),
+ TokenType.any_word ().action ((token) => { symbol_name = token.to_string (); }),
+ Rule.option ({
+ Rule.many ({
+ Rule.one_of ({
+ TokenType.any_word ().action ((token) => { symbol_name += token.to_string (); }),
+ TokenType.MINUS.action ((token => { symbol_name += token.to_string (); }))
+ })
+ })
+ })
+ });
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings) {
+
+ if (symbol_name.has_prefix ("c::")) {
+ _symbol_name = _symbol_name.substring (3);
+ string? singular_symbol_name = (c_accept_plural && _symbol_name.has_suffix ("s"))
+ ? symbol_name.substring (0, _symbol_name.length - 1)
+ : null;
+
+ _symbol = api_root.search_symbol_cstr (container, symbol_name);
+ if (_symbol == null && singular_symbol_name != null) {
+ _symbol = api_root.search_symbol_cstr (container, singular_symbol_name);
+ c_is_plural = true;
+ }
+ _context = SymbolContext.NORMAL;
+
+ if (_symbol == null && _symbol_name.has_suffix ("_finish")) {
+ string tmp = _symbol_name.substring (0, _symbol_name.length - 7);
+
+ _symbol = api_root.search_symbol_cstr (container, tmp + "_async") as Api.Method;
+ if (_symbol != null && ((Api.Method) _symbol).is_yields) {
+ _context = SymbolContext.FINISH;
+ } else {
+ _symbol = api_root.search_symbol_cstr (container, tmp) as Api.Method;
+ if (_symbol != null && ((Api.Method) _symbol).is_yields) {
+ _context = SymbolContext.FINISH;
+ } else {
+ _symbol = null;
+ }
+ }
+ }
+
+ if (_symbol == null) {
+ _symbol = api_root.search_symbol_type_cstr (symbol_name);
+ if (_symbol == null && singular_symbol_name != null) {
+ _symbol = api_root.search_symbol_type_cstr (singular_symbol_name);
+ c_is_plural = true;
+ }
+ if (_symbol != null) {
+ _context = SymbolContext.TYPE;
+ }
+ }
+
+ if (_symbol != null) {
+ symbol_name = _symbol.name;
+ }
+ } else {
+ _symbol = api_root.search_symbol_str (container, symbol_name);
+ }
+
+ if (_symbol == null && symbol_name != "main") {
+ string node_segment = (container is Api.Package)? "" : container.get_full_name () + ": ";
+ reporter.simple_warning ("%s: %s@link".printf (file_path, node_segment),
+ "`%s' does not exist", symbol_name);
+ }
+
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override ContentElement produce_content () {
+ var link = new Content.SymbolLink ();
+ link.symbol = _symbol;
+ link.given_symbol_name = symbol_name;
+
+ Content.Inline content;
+ switch (_context) {
+ case SymbolContext.FINISH:
+ link.given_symbol_name += ".end";
+ content = link;
+ break;
+
+ case SymbolContext.TYPE:
+ Run run = new Content.Run (Run.Style.MONOSPACED);
+ content = run;
+
+ Content.Run keyword = new Content.Run (Run.Style.LANG_KEYWORD);
+ keyword.content.add (new Content.Text ("typeof"));
+ run.content.add (keyword);
+
+ run.content.add (new Content.Text (" ("));
+ run.content.add (link);
+ run.content.add (new Content.Text (")"));
+ break;
+
+ default:
+ content = link;
+ break;
+ }
+
+ if (c_is_plural == true) {
+ Run run = new Content.Run (Run.Style.NONE);
+ run.content.add (content);
+ run.content.add (new Content.Text ("s"));
+ return run;
+ }
+
+ return content;
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Link link = new Link ();
+ link.parent = new_parent;
+
+ link.settings = settings;
+ link.locator = locator;
+
+ link.symbol_name = symbol_name;
+ link.c_accept_plural = c_accept_plural;
+ link.c_is_plural = c_is_plural;
+ link._context = _context;
+ link._symbol = _symbol;
+
+ return link;
+ }
+ }
--- /dev/null
-using Valadoc.Content;
-using Gee;
+ /* taglet.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- Gee.List<Api.Node> params = container.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false);
+
++using Valadoc.Content;
+
+ public class Valadoc.Taglets.Param : BlockContent, Taglet, Block {
+ public string parameter_name { internal set; get; }
+
+ public weak Api.Symbol? parameter { private set; get; }
+
+ public int position { private set; get; default = -1; }
+
+ public bool is_c_self_param { internal set; get; }
+
+ public bool is_this { private set; get; }
+
+
+ public Rule? get_parser_rule (Rule run_rule) {
+ return Rule.seq ({
+ Rule.option ({ Rule.many ({ TokenType.SPACE }) }),
+ TokenType.any_word ().action ((token) => { parameter_name = token.to_string (); }),
+ run_rule
+ });
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // Check for the existence of such a parameter
+ unowned string? implicit_return_array_length = null;
+ bool has_instance = has_instance (container);
+ bool is_implicit = false;
+ this.parameter = null;
+
+ if (container is Api.Callable) {
+ implicit_return_array_length = ((Api.Callable) container).implicit_array_length_cparameter_name;
+ } else {
+ reporter.simple_warning ("%s: %s: @param".printf (file_path, container.get_full_name ()),
+ "@param used outside method/delegate/signal context");
+ base.check (api_root, container, file_path, reporter, settings);
+ return ;
+ }
+
+ if (is_c_self_param == true && has_instance) {
+ this.parameter_name = "this";
+ this.is_this = true;
+ this.position = 0;
+ } else if (parameter_name == "...") {
- Gee.List<Api.Node> params = container.get_children_by_types ({Api.NodeType.FORMAL_PARAMETER,
++ Vala.List<Api.Node> params = container.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false);
+ foreach (Api.Node param in params) {
+ if (((Api.FormalParameter) param).ellipsis) {
+ this.parameter = (Api.Symbol) param;
+ this.position = (has_instance)? params.size : params.size - 1;
+ break;
+ }
+ }
+ } else {
- public Gee.List<ContentElement>? get_inheritable_documentation () {
++ Vala.List<Api.Node> params = container.get_children_by_types ({Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.TYPE_PARAMETER},
+ false);
+ int pos = (has_instance)? 1 : 0;
+
+ foreach (Api.Node param in params) {
+ if (param.name == parameter_name) {
+ this.parameter = (Api.Symbol) param;
+ this.position = pos;
+ break;
+ }
+
+ Api.FormalParameter formalparam = param as Api.FormalParameter;
+ if (formalparam != null && (formalparam.implicit_array_length_cparameter_name == parameter_name
+ || formalparam.implicit_closure_cparameter_name == parameter_name
+ || formalparam.implicit_destroy_cparameter_name == parameter_name))
+ {
+ is_implicit = true;
+ break;
+ }
+
+ pos++;
+ }
+
+ if (this.parameter == null
+ && (parameter_name == "error"
+ && container.has_children ({Api.NodeType.ERROR_DOMAIN, Api.NodeType.CLASS})
+ || parameter_name == implicit_return_array_length))
+ {
+ is_implicit = true;
+ }
+ }
+
+ if (this.parameter == null) {
+ if (is_implicit) {
+ reporter.simple_note ("%s: %s: @param".printf (file_path, container.get_full_name ()),
+ "Implicit parameter `%s' exposed in documentation", parameter_name);
+ } else if (!is_c_self_param) {
+ reporter.simple_warning ("%s: %s: @param".printf (file_path, container.get_full_name ()),
+ "Unknown parameter `%s'", parameter_name);
+ }
+ }
+
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ private bool has_instance (Api.Item element) {
+ if (element is Api.Method) {
+ return !((Api.Method) element).is_static;
+ }
+
+ return false;
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_taglet (this);
+ }
+
++ public Vala.List<ContentElement>? get_inheritable_documentation () {
+ return content;
+ }
+
+ public bool inheritable (Taglet taglet) {
+ if (taglet is Taglets.Param == false) {
+ return false;
+ }
+
+ Taglets.Param t = (Taglets.Param) taglet;
+ return (parameter == t.parameter || parameter_name == t.parameter_name);
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Param param = new Param ();
+ param.parent = new_parent;
+
+ param.parameter_name = parameter_name;
+ param.parameter = parameter;
+ param.position = position;
+
+ foreach (Block element in content) {
+ Block copy = element.copy (param) as Block;
+ param.content.add (copy);
+ }
+
+ return param;
+ }
+ }
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* taglet.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- public Gee.List<ContentElement>? get_inheritable_documentation () {
+
++using Valadoc.Content;
+
+ public class Valadoc.Taglets.Return : BlockContent, Taglet, Block {
+ public Rule? get_parser_rule (Rule run_rule) {
+ return run_rule;
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings) {
+ Api.TypeReference? type_ref = null;
+ bool creation_method = false;
+
+ if (container is Api.Method) {
+ creation_method = ((Api.Method) container).is_constructor;
+ type_ref = ((Api.Method) container).return_type;
+ } else if (container is Api.Callable) {
+ type_ref = ((Api.Callable) container).return_type;
+ } else {
+ reporter.simple_warning ("%s: %s: @return".printf (file_path, container.get_full_name ()),
+ "@return used outside method/delegate/signal context");
+ }
+
+ if (type_ref != null && type_ref.data_type == null && !creation_method) {
+ reporter.simple_warning ("%s: %s: @return".printf (file_path, container.get_full_name ()),
+ "Return description declared for void function");
+ }
+
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_taglet (this);
+ }
+
++ public Vala.List<ContentElement>? get_inheritable_documentation () {
+ return content;
+ }
+
+ public bool inheritable (Taglet taglet) {
+ return taglet is Taglets.Return;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Return ret = new Return ();
+ ret.parent = new_parent;
+
+ foreach (Block element in content) {
+ Block copy = element.copy (ret) as Block;
+ ret.content.add (copy);
+ }
+
+ return ret;
+ }
+ }
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* tagletsee.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
++using Valadoc.Content;
+
+ public class Valadoc.Taglets.See : ContentElement, Taglet, Block {
+ public string symbol_name { private set; get; }
+ public Api.Node symbol { private set; get; }
+
+ public Rule? get_parser_rule (Rule run_rule) {
+ Rule optional_spaces = Rule.option ({ Rule.many ({ TokenType.SPACE }) });
+
+ return Rule.seq ({
+ optional_spaces,
+ TokenType.any_word ().action ((token) => { symbol_name = token.to_string (); }),
+ optional_spaces
+ });
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings) {
+ if (symbol_name.has_prefix ("c::")) {
+ symbol_name = symbol_name.substring (3);
+ symbol = api_root.search_symbol_cstr (container, symbol_name);
+ if (symbol != null) {
+ symbol_name = _symbol.name;
+ }
+ } else {
+ symbol = api_root.search_symbol_str (container, symbol_name);
+ }
+
+ if (symbol == null) {
+ // TODO use ContentElement's source reference
+ reporter.simple_warning ("%s: %s: @see".printf (file_path, container.get_full_name ()),
+ "`%s' does not exist", symbol_name);
+ }
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_taglet (this);
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ See see = new See ();
+ see.parent = new_parent;
+
+ see.symbol_name = symbol_name;
+ see.symbol = symbol;
+
+ return see;
+ }}
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* tagletsince.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+
++using Valadoc.Content;
+
+ public class Valadoc.Taglets.Since : ContentElement, Taglet, Block {
+ public string version { get; internal set; }
+
+ public Rule? get_parser_rule (Rule run_rule) {
+ Rule optional_spaces = Rule.option ({ Rule.many ({ TokenType.SPACE }) });
+
+ return Rule.seq ({
+ optional_spaces,
+ TokenType.any_word ().action ((token) => { version = token.to_string (); }),
+ optional_spaces
+ });
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_taglet (this);
+ }
+
+ public override bool is_empty () {
+ return false;
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Since since = new Since ();
+ since.parent = new_parent;
+
+ since.version = version;
+
+ return since;
+ }
+ }
+
--- /dev/null
-using Gee;
-using Valadoc.Content;
+ /* tagletthrows.vala
+ *
+ * Copyright (C) 2008-2009 Didier Villevalois
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
- Gee.List<Api.Node> exceptions = container.get_children_by_types ({Api.NodeType.ERROR_DOMAIN,
+
++using Valadoc.Content;
+
+ public class Valadoc.Taglets.Throws : BlockContent, Taglet, Block {
+ // TODO: rename
+ public string error_domain_name { private set; get; }
+
+ /**
+ * Thrown Error domain or Error code
+ */
+ // TODO: rename
+ public Api.Node error_domain { private set; get; }
+
+ public Rule? get_parser_rule (Rule run_rule) {
+ return Rule.seq ({
+ Rule.option ({ Rule.many ({ TokenType.SPACE }) }),
+ TokenType.any_word ().action ((token) => { error_domain_name = token.to_string (); }),
+ run_rule
+ });
+ }
+
+ public override void check (Api.Tree api_root, Api.Node container, string file_path,
+ ErrorReporter reporter, Settings settings)
+ {
+ // context check:
+ if (container is Api.Method == false && container is Api.Delegate == false) {
+ reporter.simple_warning ("%s: %s: @throws".printf (file_path, container.get_full_name ()),
+ "@throws used outside method/delegate context");
+ base.check (api_root, container, file_path, reporter, settings);
+ return ;
+ }
+
+
+ // type check:
+ error_domain = api_root.search_symbol_str (container, error_domain_name);
+ if (error_domain == null) {
+ // TODO use ContentElement's source reference
+ reporter.simple_error ("%s: %s: @throws".printf (file_path, container.get_full_name ()),
+ "`%s' does not exist", error_domain_name);
+ base.check (api_root, container, file_path, reporter, settings);
+ return ;
+ }
+
+
+ // Check if the method is allowed to throw the given type or error code:
- public Gee.List<ContentElement>? get_inheritable_documentation () {
++ Vala.List<Api.Node> exceptions = container.get_children_by_types ({Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.CLASS},
+ false);
+ Api.Item expected_error_domain = (error_domain is Api.ErrorCode)
+ ? error_domain.parent
+ : error_domain;
+ bool report_warning = true;
+ foreach (Api.Node exception in exceptions) {
+ if (exception == expected_error_domain
+ || (exception is Api.Class && expected_error_domain is Api.ErrorDomain))
+ {
+ report_warning = false;
+ break;
+ }
+ }
+ if (report_warning) {
+ reporter.simple_warning ("%s: %s: @throws".printf (file_path, container.get_full_name ()),
+ "`%s' does not exist in exception list", error_domain_name);
+ }
+
+ base.check (api_root, container, file_path, reporter, settings);
+ }
+
+ public override void accept (ContentVisitor visitor) {
+ visitor.visit_taglet (this);
+ }
+
++ public Vala.List<ContentElement>? get_inheritable_documentation () {
+ return content;
+ }
+
+ public bool inheritable (Taglet taglet) {
+ if (taglet is Taglets.Throws == false) {
+ return false;
+ }
+
+ Taglets.Throws t = (Taglets.Throws) taglet;
+ return (error_domain == t.error_domain || error_domain_name == t.error_domain_name);
+ }
+
+ public override ContentElement copy (ContentElement? new_parent = null) {
+ Throws tr = new Throws ();
+ tr.parent = new_parent;
+
+ tr.error_domain_name = error_domain_name;
+ tr.error_domain = error_domain;
+
+ foreach (Block element in content) {
+ Block copy = element.copy (tr) as Block;
+ tr.content.add (copy);
+ }
+
+ return tr;
+ }
+ }
+
--- /dev/null
--- /dev/null
++gmodule-2.0
++libgvc
++libvala@PACKAGE_SUFFIX@
--- /dev/null
-libdir=@libdir@/valadoc/
+ prefix=@prefix@
+ exec_prefix=@exec_prefix@
-Requires: libgvc gee-0.8 gmodule-2.0
-Libs: -L${libdir} -lvaladoc
-Cflags: -I${includedir}/valadoc-1.0
++libdir=@libdir@
+ includedir=@includedir@
+ datarootdir=@datarootdir@
+ datadir=@datadir@
+ vapidir=@datadir@/vala/vapi
+
+ Name: Valadoc
+ Description: The Vala documentation compiler library
+ Version: @VERSION@
++Requires: gmodule-2.0 libgvc libvala@PACKAGE_SUFFIX@
++Libs: -L${libdir} -lvaladoc@PACKAGE_SUFFIX@
++Cflags: -I${includedir}/valadoc@PACKAGE_SUFFIX@
--- /dev/null
--- /dev/null
++valadoc
++tests/driver
--- /dev/null
-DEFAULT_DRIVER = $(shell $(VALAC) --api-version >/dev/null 2>&1; if [ $$? = 0 ]; then $(VALAC) --api-version; else $(VALAC) --version; fi)
++include $(top_srcdir)/Makefile.common
++
+ NULL =
+
- -DDEFAULT_DRIVER=\"$(DEFAULT_DRIVER)\" \
- -I $(top_builddir)/src/libvaladoc/ \
++SUBDIRS = \
++ doclets \
++ icons \
++ tests \
++ $(NULL)
+
+ AM_CFLAGS = \
+ -DPACKAGE_DATADIR=\"$(libdir)/valadoc\" \
+ -DPACKAGE_VERSION=\"$(VERSION)\" \
- $(LIBGEE_CFLAGS) \
++ -I$(top_srcdir)/libvaladoc/ \
++ -I$(top_srcdir)/gee \
++ -I$(top_srcdir)/ccode \
++ -I$(top_srcdir)/vala \
++ -I$(top_srcdir)/codegen \
+ $(GLIB_CFLAGS) \
- -g \
- -w \
- $(NULL)
-
-AM_VALAFLAGS = \
- $(VALAFLAGS) \
- --vapidir $(top_srcdir)/src/vapi/ \
- --vapidir $(top_builddir)/src/libvaladoc/ \
- --basedir $(srcdir) \
- --directory $(builddir) \
- -C \
- -g \
+ $(GMODULE_CFLAGS) \
+ $(LIBGVC_CFLAGS) \
-nodist_valadoc_SOURCES = \
+ $(NULL)
+
+ BUILT_SOURCES = valadoc.vala.stamp
+
+ bin_PROGRAMS = valadoc
+
+ valadoc_VALASOURCES = \
++ driver.vala \
++ girwriter.vala \
++ initializerbuilder.vala \
++ symbolresolver.vala \
++ treebuilder.vala \
+ valadoc.vala \
+ $(NULL)
+
- $(top_builddir)/src/libvaladoc/libvaladoc.la \
++valadoc_SOURCES = \
++ valadoc.vala.stamp \
+ $(valadoc_VALASOURCES:.vala=.c) \
+ $(NULL)
+
+ valadoc_LDADD = \
- $(LIBGEE_LIBS) \
++ $(top_builddir)/libvaladoc/libvaladoc@PACKAGE_SUFFIX@.la \
++ $(top_builddir)/vala/libvala@PACKAGE_SUFFIX@.la \
++ $(top_builddir)/ccode/libvalaccode.la \
++ $(top_builddir)/codegen/libvalaccodegen.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(LIBGVC_LIBS) \
-valadoc.vala.stamp: $(valadoc_VALASOURCES) Makefile
- $(VALAC) \
- $(AM_VALAFLAGS) \
- --pkg config \
- --pkg gee-0.8 \
+ $(NULL)
+
- --pkg valadoc-1.0 \
++valadoc.vala.stamp: $(valadoc_VALASOURCES) $(top_srcdir)/vala/libvala@PACKAGE_SUFFIX@.vapi $(top_srcdir)/libvaladoc/valadoc@PACKAGE_SUFFIX@.vapi
++ $(VALA_V)$(VALAC) \
++ $(VALAFLAGS) \
++ -C \
++ --vapidir $(top_srcdir)/vala \
++ --vapidir $(top_srcdir)/vapi \
+ --pkg gmodule-2.0 \
-CLEANFILES = \
- $(BUILT_SOURCES) \
- $(nodist_valadoc_SOURCES) \
- $(NULL)
++ --pkg gobject-2.0 \
++ --vapidir $(top_srcdir)/ccode --pkg ccode \
++ --vapidir $(top_srcdir)/codegen --pkg codegen \
++ --vapidir $(top_srcdir)/libvaladoc --pkg valadoc@PACKAGE_SUFFIX@ \
++ --pkg config \
+ $(filter %.vala %.c,$^)
+ touch $@
+
+ EXTRA_DIST = \
+ $(valadoc_VALASOURCES) \
++ valadoc.vala.stamp \
+ $(NULL)
+
++if ENABLE_UNVERSIONED
++install-exec-hook:
++ cd $(DESTDIR)$(bindir) && $(LN_S) -f valadoc@PACKAGE_SUFFIX@$(EXEEXT) valadoc$(EXEEXT)
++endif
+
++MAINTAINERCLEANFILES = \
++ $(valadoc_VALASOURCES:.vala=.c) \
++ $(NULL)
--- /dev/null
- -I $(top_builddir)/src/libvaladoc/ \
++include $(top_srcdir)/Makefile.common
++
+ NULL =
+
+ AM_CFLAGS = \
+ -DPACKAGE_ICONDIR=\"$(datadir)/valadoc/icons/\" \
- $(LIBGEE_CFLAGS) \
++ -I$(top_srcdir)/gee/ \
++ -I$(top_srcdir)/libvaladoc/ \
+ $(GLIB_CFLAGS) \
- -g \
- -w \
- $(NULL)
-
-AM_VALAFLAGS = \
- $(VALAFLAGS) \
- --vapidir $(top_srcdir)/src/vapi \
- --vapidir $(top_builddir)/src/libvaladoc \
- --basedir $(srcdir) \
- --directory $(builddir) \
- -C \
- -g \
+ $(LIBGVC_CFLAGS) \
-nodist_libdoclet_la_SOURCES = \
+ $(NULL)
+
+ BUILT_SOURCES = libdoclet.vala.stamp
+
+ doclet_LTLIBRARIES = libdoclet.la
+
+ docletdir = $(libdir)/valadoc/doclets/devhelp
+
+ libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
+
+ libdoclet_la_VALASOURCES = \
+ doclet.vala \
+ $(NULL)
+
-libdoclet.vala.stamp: $(libdoclet_la_VALASOURCES) Makefile
- $(VALAC) \
- $(AM_VALAFLAGS) \
- --pkg gee-0.8 \
- --pkg valadoc-1.0 \
++libdoclet_la_SOURCES = \
++ libdoclet.vala.stamp \
+ $(libdoclet_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
- $(top_builddir)/src/libvaladoc/libvaladoc.la \
++libdoclet.vala.stamp: $(libdoclet_la_VALASOURCES)
++ $(VALA_V)$(VALAC) \
++ $(VALAFLAGS) \
++ -C \
++ --vapidir $(top_srcdir)/vala \
++ --vapidir $(top_srcdir)/vapi \
++ --vapidir $(top_srcdir)/libvaladoc --pkg valadoc@PACKAGE_SUFFIX@ \
+ $(filter %.vala %.c,$^)
+ touch $@
+
+ libdoclet_la_LIBADD = \
- $(LIBGEE_LIBS) \
++ $(top_builddir)/libvaladoc/libvaladoc@PACKAGE_SUFFIX@.la \
+ $(GLIB_LIBS) \
-CLEANFILES = \
- $(BUILT_SOURCES) \
- $(nodist_libdoclet_la_SOURCES) \
+ $(NULL)
+
+ EXTRA_DIST = \
+ $(libdoclet_la_VALASOURCES) \
++ libdoclet.vala.stamp \
+ $(NULL)
+
++MAINTAINERCLEANFILES = \
++ $(libdoclet_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
--- /dev/null
-using Gee;
-
-
+ /* doclet.vala
+ *
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
++
+ using Valadoc;
+ using Valadoc.Api;
+ using Valadoc.Html;
- private ArrayList<Api.Node> nodes = new ArrayList<Api.Node> ();
+
+ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
+ private const string css_path_wiki = "devhelpstyle.css";
+ private const string css_path = "devhelpstyle.css";
+
+ private const string js_path_wiki = "scripts.js";
+ private const string js_path = "scripts.js";
+
+
++ private Vala.ArrayList<Api.Node> nodes = new Vala.ArrayList<Api.Node> ();
+ private string package_dir_name = ""; // remove
+
+ private Devhelp.MarkupWriter _devhelpwriter;
+
+ private string get_path (Api.Node element) {
+ return element.get_full_name () + ".html";
+ }
+
+ private string get_real_path (Api.Node element) {
+ return GLib.Path.build_filename (this.settings.path,
+ this.package_dir_name, element.get_full_name () + ".html");
+ }
+
+ protected override string get_icon_directory () {
+ return "";
+ }
+
+
+ public override void process (Settings settings, Api.Tree tree, ErrorReporter reporter) {
+ base.process (settings, tree, reporter);
+ DirUtils.create_with_parents (this.settings.path, 0777);
+ write_wiki_pages (tree,
+ css_path_wiki,
+ js_path_wiki,
+ Path.build_filename (this.settings.path, this.settings.pkg_name));
+ tree.accept (this);
+ }
+
+ public override void visit_tree (Api.Tree tree) {
+ tree.accept_children (this);
+ }
+
+ public override void visit_package (Package package) {
+ if (!package.is_browsable (settings)) {
+ return ;
+ }
+
+ string pkg_name = package.name;
+
+ string path = GLib.Path.build_filename (this.settings.path, pkg_name);
+ string filepath = GLib.Path.build_filename (path, "index.htm");
+ string imgpath = GLib.Path.build_filename (path, "img");
+ string devpath = GLib.Path.build_filename (path, pkg_name + ".devhelp2");
+
+ this.package_dir_name = pkg_name;
+
+ var rt = DirUtils.create (path, 0777);
+ rt = DirUtils.create (imgpath, 0777);
+ copy_directory (icons_dir, path);
+
+ var devfile = FileStream.open (devpath, "w");
+ _devhelpwriter = new Devhelp.MarkupWriter (devfile);
+
+ _devhelpwriter.start_book (pkg_name+" Reference Manual",
+ "vala",
+ "index.htm",
+ pkg_name,
+ "",
+ "");
+
+ GLib.FileStream file = GLib.FileStream.open (filepath, "w");
+ writer = new Html.MarkupWriter (file);
+ _renderer.set_writer (writer);
+ write_file_header (Valadoc.Devhelp.Doclet.css_path, Valadoc.Devhelp.Doclet.js_path, pkg_name);
+ write_package_content (package, package);
+ write_file_footer ();
+ file = null;
+
+
+ _devhelpwriter.start_chapters ();
+ package.accept_all_children (this);
+ _devhelpwriter.end_chapters ();
+
+ _devhelpwriter.start_functions ();
+ foreach (Api.Node node in this.nodes) {
+ string typekeyword = "";
+ if (node is Api.Enum) {
+ typekeyword = "enum";
+ } else if (node is Api.Constant) {
+ typekeyword = "constant";
+ } else if (node is Api.Method) {
+ typekeyword = "function";
+ } else if (node is Api.Field) {
+ typekeyword = "variable";
+ } else if (node is Api.Property) {
+ typekeyword = "property";
+ } else if (node is Api.Signal) {
+ typekeyword = "signal";
+ } else if (node is Api.Struct) {
+ typekeyword = "struct";
+ }
+
+ _devhelpwriter.simple_tag ("keyword", {"type", typekeyword,
+ "name", node.get_full_name (),
+ "link", get_link (node, node.package)});
+ }
+ _devhelpwriter.end_functions ();
+
+ _devhelpwriter.end_book ();
+ }
+
+ private void process_compound_node (Api.Node node) {
+ string rpath = this.get_real_path (node);
+ string path = this.get_path (node);
+
+ if (node.name != null) {
+ GLib.FileStream file = GLib.FileStream.open (rpath, "w");
+ writer = new Html.MarkupWriter (file);
+ _renderer.set_writer (writer);
+ write_file_header (css_path,
+ js_path,
+ node.get_full_name () + " – " + node.package.name);
+ write_symbol_content (node);
+ write_file_footer ();
+ file = null;
+ }
+
+ if (node.name != null) {
+ _devhelpwriter.start_sub (node.name, path);
+ node.accept_all_children (this);
+ _devhelpwriter.end_sub ();
+ this.nodes.add (node);
+ } else {
+ node.accept_all_children (this);
+ }
+ }
+
+ private void process_node (Api.Node node, bool accept_all_children) {
+ string rpath = this.get_real_path (node);
+ string path = this.get_path (node);
+
+ GLib.FileStream file = GLib.FileStream.open (rpath, "w");
+ writer = new Html.MarkupWriter (file);
+ _renderer.set_writer (writer);
+ write_file_header (css_path,
+ js_path,
+ node.get_full_name() + " – " + node.package.name);
+ write_symbol_content (node);
+ write_file_footer ();
+ file = null;
+
+ if (accept_all_children) {
+ _devhelpwriter.start_sub (node.name, path);
+ node.accept_all_children (this);
+ _devhelpwriter.end_sub ();
+ }
+ this.nodes.add (node);
+ }
+
+ public override void visit_namespace (Namespace item) {
+ process_compound_node (item);
+ }
+
+ public override void visit_interface (Interface item) {
+ process_compound_node (item);
+ }
+
+ public override void visit_class (Class item) {
+ process_compound_node (item);
+ }
+
+ public override void visit_struct (Struct item) {
+ process_compound_node (item);
+ }
+
+ public override void visit_error_domain (ErrorDomain item) {
+ process_node (item, true);
+ }
+
+ public override void visit_enum (Api.Enum item) {
+ process_node (item, true);
+ }
+
+ public override void visit_property (Property item) {
+ process_node (item, false);
+ }
+
+ public override void visit_constant (Constant item) {
+ process_node (item, false);
+ }
+
+ public override void visit_field (Field item) {
+ process_node (item, false);
+ }
+
+ public override void visit_error_code (ErrorCode item) {
+ process_node (item, false);
+ }
+
+ public override void visit_enum_value (Api.EnumValue item) {
+ process_node (item, false);
+ }
+
+ public override void visit_delegate (Delegate item) {
+ process_node (item, false);
+ }
+
+ public override void visit_signal (Api.Signal item) {
+ process_node (item, false);
+ }
+
+ public override void visit_method (Method item) {
+ process_node (item, false);
+ }
+ }
+
+
+ public Type register_plugin (Valadoc.ModuleLoader module_loader) {
+ return typeof (Valadoc.Devhelp.Doclet);
+ }
+
--- /dev/null
- -I $(top_builddir)/src/libvaladoc/ \
++include $(top_srcdir)/Makefile.common
++
+ NULL =
+
+ AM_CFLAGS = \
+ -DPACKAGE_ICONDIR=\"$(datadir)/valadoc/icons/\" \
- $(LIBGEE_CFLAGS) \
++ -I$(top_srcdir)/gee/ \
++ -I$(top_srcdir)/libvaladoc/ \
+ $(GLIB_CFLAGS) \
- -g \
- -w \
- $(NULL)
-
-AM_VALAFLAGS = \
- $(VALAFLAGS) \
- --vapidir $(top_srcdir)/src/vapi \
- --vapidir $(top_builddir)/src/libvaladoc \
- --basedir $(srcdir) \
- --directory $(builddir) \
- -C \
- -g \
+ $(LIBGVC_CFLAGS) \
-nodist_libdoclet_la_SOURCES = \
+ $(NULL)
+
+ BUILT_SOURCES = libdoclet.vala.stamp
+
+ doclet_LTLIBRARIES = libdoclet.la
+
+ docletdir = $(libdir)/valadoc/doclets/gtkdoc
+
+ libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
+
+ libdoclet_la_VALASOURCES = \
+ commentconverter.vala \
+ dbus.vala \
+ doclet.vala \
+ gcomment.vala \
+ generator.vala \
+ utils.vala \
+ $(NULL)
+
-libdoclet.vala.stamp: $(libdoclet_la_VALASOURCES) Makefile
- $(VALAC) \
- $(AM_VALAFLAGS) \
- --pkg gee-0.8 \
- --pkg valadoc-1.0 \
++libdoclet_la_SOURCES = \
++ libdoclet.vala.stamp \
+ $(libdoclet_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
- $(top_builddir)/src/libvaladoc/libvaladoc.la \
++libdoclet.vala.stamp: $(libdoclet_la_VALASOURCES)
++ $(VALA_V)$(VALAC) \
++ $(VALAFLAGS) \
++ -C \
++ --vapidir $(top_srcdir)/vala \
++ --vapidir $(top_srcdir)/vapi \
++ --vapidir $(top_srcdir)/libvaladoc --pkg valadoc@PACKAGE_SUFFIX@ \
+ $(filter %.vala %.c,$^)
+ touch $@
+
+ libdoclet_la_LIBADD = \
- $(LIBGEE_LIBS) \
++ $(top_builddir)/libvaladoc/libvaladoc@PACKAGE_SUFFIX@.la \
+ $(GLIB_LIBS) \
-CLEANFILES = \
- $(BUILT_SOURCES) \
- $(nodist_libdoclet_la_SOURCES) \
+ $(NULL)
+
+ EXTRA_DIST = \
+ $(libdoclet_la_VALASOURCES) \
++ libdoclet.vala.stamp \
+ $(NULL)
+
++MAINTAINERCLEANFILES = \
++ $(libdoclet_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
--- /dev/null
- public Gee.List<Header> parameters = new Gee.LinkedList<Header> ();
- public Gee.List<Header> versioning = new Gee.LinkedList<Header> ();
+ /* commentconverter.vala
+ *
+ * Copyright (C) 2010 Luca Bruno
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Luca Bruno <lethalman88@gmail.com>
+ */
+
+ using Valadoc;
+ using Valadoc.Api;
+ using Valadoc.Content;
+
+ public class Gtkdoc.CommentConverter : ContentVisitor {
+ public Api.Node node_reference;
+
+ public bool is_dbus;
+ public string brief_comment;
+ public string long_comment;
+ public string returns;
++ public Vala.List<Header> parameters = new Vala.ArrayList<Header> ();
++ public Vala.List<Header> versioning = new Vala.ArrayList<Header> ();
+ public string[] see_also = new string[]{};
+
+ private StringBuilder current_builder = new StringBuilder ();
+ private bool in_brief_comment = true;
+ private ErrorReporter reporter;
+
+ public CommentConverter (ErrorReporter reporter, Api.Node? node_reference = null) {
+ this.node_reference = node_reference;
+ this.reporter = reporter;
+ }
+
+ public void convert (Content.Comment comment, bool is_dbus = false) {
+ this.is_dbus = is_dbus;
+ comment.accept (this);
+
+ long_comment = current_builder.str.strip ();
+ if (long_comment == "") {
+ long_comment = null;
+ }
+ }
+
+ public override void visit_comment (Content.Comment c) {
+ c.accept_children (this);
+ }
+
+ public override void visit_embedded (Embedded em) {
+ current_builder.append ("<figure>");
+ if (em.caption != null) {
+ current_builder.append_printf ("<title>%s</title>", em.caption);
+ }
+
+ current_builder.append_printf ("<mediaobject><imageobject><imagedata fileref=\"%s\"/></imageobject>",
+ em.url);
+
+ if (em.caption != null) {
+ current_builder.append_printf ("<textobject><phrase>%s</phrase></textobject>", em.caption);
+ }
+
+ em.accept_children (this);
+ current_builder.append ("</mediaobject>");
+ current_builder.append ("</figure>");
+ }
+
+ public override void visit_headline (Headline hl) {
+ // what to do here?
+ reporter.simple_warning ("GtkDoc", "Headline elements not supported");
+ current_builder.append ("\n");
+ hl.accept_children (this);
+ current_builder.append ("\n");
+ }
+
+ public override void visit_wiki_link (WikiLink link) {
+ // wiki pages are not supported right now
+ if (link.content.size > 0) {
+ link.accept_children (this);
+ } else {
+ current_builder.append (link.name);
+ }
+ }
+
+ public override void visit_link (Link link) {
+ current_builder.append_printf ("<ulink url=\"%s\">", link.url);
+ link.accept_children (this);
+ current_builder.append ("</ulink>");
+ }
+
+ public override void visit_symbol_link (SymbolLink sl) {
+ if (sl.symbol != null) {
+ // If the symbol is a method and it doesn't have a constructor, fall back to linking to the class
+ if (sl.symbol is Method && ((Method) sl.symbol).is_constructor &&
+ ((Method) sl.symbol).parent is Class && ((Class) ((Method) sl.symbol).parent).is_abstract) {
+ current_builder.append (get_docbook_link (((Method) sl.symbol).parent, is_dbus) ?? sl.given_symbol_name);
+ } else {
+ current_builder.append (get_docbook_link (sl.symbol, is_dbus) ?? sl.given_symbol_name);
+ }
+ } else {
+ current_builder.append (sl.given_symbol_name);
+ }
+ }
+
+ public override void visit_list (Content.List list) {
+ string tag = "orderedlist";
+ switch (list.bullet) {
+ case Content.List.Bullet.NONE:
+ current_builder.append ("<itemizedlist mark=\"none\">");
+ tag = "itemizedlist";
+ break;
+
+ case Content.List.Bullet.UNORDERED:
+ current_builder.append ("<itemizedlist>");
+ tag = "itemizedlist";
+ break;
+
+ case Content.List.Bullet.ORDERED:
+ current_builder.append ("<orderedlist>");
+ break;
+
+ case Content.List.Bullet.ORDERED_NUMBER:
+ current_builder.append ("<orderedlist numeration=\"arabic\">");
+ break;
+
+ case Content.List.Bullet.ORDERED_LOWER_CASE_ALPHA:
+ current_builder.append ("<orderedlist numeration=\"loweralpha\">");
+ break;
+
+ case Content.List.Bullet.ORDERED_UPPER_CASE_ALPHA:
+ current_builder.append ("<orderedlist numeration=\"upperalpha\">");
+ break;
+
+ case Content.List.Bullet.ORDERED_LOWER_CASE_ROMAN:
+ current_builder.append ("<orderedlist numeration=\"lowerroman\">");
+ break;
+
+ case Content.List.Bullet.ORDERED_UPPER_CASE_ROMAN:
+ current_builder.append ("<orderedlist numeration=\"upperroman\">");
+ break;
+
+ default:
+ reporter.simple_warning ("GtkDoc",
+ "unsupported list type: '%s'", list.bullet.to_string ());
+ break;
+ }
+
+ list.accept_children (this);
+ current_builder.append_printf ("</%s>", tag);
+ }
+
+ public override void visit_list_item (ListItem item) {
+ current_builder.append ("<listitem>");
+ item.accept_children (this);
+ current_builder.append ("</listitem>");
+ }
+
+ public override void visit_paragraph (Paragraph para) {
+ if (!in_brief_comment) {
+ current_builder.append ("<para>");
+ }
+ para.accept_children (this);
+
+ if (in_brief_comment) {
+ brief_comment = current_builder.str;
+ current_builder = new StringBuilder ();
+ in_brief_comment = false;
+ } else {
+ current_builder.append ("</para>");
+ }
+ }
+
+ public override void visit_warning (Warning element) {
+ current_builder.append ("<warning>");
+ element.accept_children (this);
+ current_builder.append ("</warning>");
+ }
+
+ public override void visit_note (Note element) {
+ current_builder.append ("<note>");
+ element.accept_children (this);
+ current_builder.append ("</note>");
+ }
+
+ public override void visit_page (Page page) {
+ page.accept_children (this);
+ }
+
+ public override void visit_run (Run run) {
+ string? tag = null;
+ switch (run.style) {
+ case Run.Style.BOLD:
+ current_builder.append ("<emphasis role=\"bold\">");
+ tag = "emphasis";
+ break;
+
+ case Run.Style.ITALIC:
+ current_builder.append ("<emphasis>");
+ tag = "emphasis";
+ break;
+
+ case Run.Style.UNDERLINED:
+ current_builder.append ("<emphasis role=\"underline\">");
+ tag = "emphasis";
+ break;
+
+ case Run.Style.MONOSPACED:
+ current_builder.append ("<code>");
+ tag = "code";
+ break;
+ }
+ run.accept_children (this);
+
+ if (tag != null) {
+ current_builder.append_printf ("</%s>", tag);
+ }
+ }
+
+ public override void visit_source_code (SourceCode code) {
+ current_builder.append ("\n|[\n");
+ current_builder.append (Markup.escape_text (code.code));
+ current_builder.append ("\n]|\n");
+ }
+
+ public override void visit_table (Table t) {
+ current_builder.append ("<table>");
+ t.accept_children (this);
+ current_builder.append ("</table>");
+ }
+
+ public override void visit_table_row (TableRow row) {
+ current_builder.append ("<tr>");
+ row.accept_children (this);
+ current_builder.append ("</tr>");
+ }
+
+ public override void visit_table_cell (TableCell cell) {
+ current_builder.append ("<td>");
+ cell.accept_children (this);
+ current_builder.append ("</td>");
+ }
+
+ public override void visit_taglet (Taglet t) {
+ var old_builder = (owned)current_builder;
+ current_builder = new StringBuilder ();
+
+ t.accept_children (this);
+ if (t is Taglets.Param) {
+ double pos = double.MAX;
+ var param_name = ((Taglets.Param)t).parameter_name;
+ if (node_reference != null) {
+ pos = get_parameter_pos (node_reference, param_name);
+ }
+ var header = new Header (param_name, current_builder.str, pos);
+ parameters.add (header);
+ } else if (t is Taglets.InheritDoc) {
+ ((Taglets.InheritDoc)t).produce_content().accept (this);
+ } else if (t is Taglets.Return) {
+ returns = current_builder.str;
+ } else if (t is Taglets.Since) {
+ var header = new Header ("Since", ((Taglets.Since)t).version);
+ versioning.add (header);
+ } else if (t is Taglets.Deprecated) {
+ var header = new Header ("Deprecated", current_builder.str);
+ versioning.add (header);
+ } else if (t is Taglets.See) {
+ var see = (Taglets.See)t;
+ var see_also = this.see_also; // vala bug
+ if (see.symbol != null) {
+ see_also += get_docbook_link (see.symbol, is_dbus) ?? see.symbol_name;
+ } else {
+ see_also += see.symbol_name;
+ }
+ this.see_also = see_also;
+ } else if (t is Taglets.Link) {
+ ((Taglets.Link)t).produce_content().accept (this);
+ } else if (t is Taglets.Throws) {
+ var taglet = (Taglets.Throws) t;
+ var link = get_docbook_link (taglet.error_domain) ?? taglet.error_domain_name;
+ old_builder.append_printf ("\n<para>%s will be returned in @error %s</para>",
+ link,
+ current_builder.str);
+ } else {
+ reporter.simple_warning ("GtkDoc", "Taglet not supported"); // TODO
+ }
+ current_builder = (owned)old_builder;
+ }
+
+ public override void visit_text (Text t) {
+ current_builder.append (Markup.escape_text (t.content));
+ t.accept_children (this);
+ }
+ }
+
--- /dev/null
- public Gee.List<Parameter> parameters = new Gee.LinkedList<Parameter>();
+ /* doclet.vala
+ *
+ * Copyright (C) 2010 Luca Bruno
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Luca Bruno <lethalman88@gmail.com>
+ */
+
+ using Valadoc;
+ using Valadoc.Api;
+ using Valadoc.Content;
+
+ namespace Gtkdoc.DBus {
+ public class Parameter {
+ public enum Direction {
+ NONE,
+ IN,
+ OUT;
+
+ public string to_string () {
+ switch (this) {
+ case NONE:
+ return "";
+ case IN:
+ return "in";
+ case OUT:
+ return "out";
+ default:
+ assert_not_reached ();
+ }
+ }
+ }
+
+ public string name;
+ public string signature;
+ public Direction direction;
+
+ public Parameter (string name, string signature, Direction direction = Direction.NONE) {
+ this.name = name;
+ this.signature = signature;
+ this.direction = direction;
+ }
+
+ public string to_string () {
+ if (direction == Direction.NONE) {
+ return """<parameter><type>'%s'</type> %s</parameter>""".printf (signature, name);
+ } else {
+ return """<parameter>%s <type>'%s'</type> %s</parameter>""".printf (direction.to_string(),
+ signature,
+ name);
+ }
+ }
+ }
+
+ public class Member {
+ public string name;
- public Gee.List<Member> methods = new Gee.LinkedList<Member>();
- public Gee.List<Member> signals = new Gee.LinkedList<Member>();
++ public Vala.List<Parameter> parameters = new Vala.ArrayList<Parameter>();
+ public GComment comment;
+
+ internal DBus.Interface iface;
+
+ public Member (string name) {
+ this.name = name;
+ }
+
+ public void add_parameter (Parameter parameter) {
+ parameters.add (parameter);
+ }
+
+ public string get_docbook_id () {
+ return to_docbook_id (name);
+ }
+
+ public string to_string (int indent, bool link) {
+ var builder = new StringBuilder ();
+
+ if (link) {
+ builder.append_printf ("""
+ <link linkend="%s-%s">%s</link>%s(""",
+ iface.get_docbook_id (),
+ get_docbook_id (),
+ name,
+ string.nfill (indent-name.length, ' '));
+ } else {
+ builder.append_printf ("\n%s%s(",
+ name,
+ string.nfill (indent-name.length, ' '));
+ }
+
+ if (parameters.size > 0) {
+ builder.append (parameters[0].to_string ());
+ }
+ for (int i=1; i < parameters.size; i++) {
+ builder.append (",\n");
+ builder.append (string.nfill (indent+1, ' '));
+ builder.append (parameters[i].to_string ());
+ }
+ builder.append_c (')');
+ return builder.str;
+ }
+ }
+
+ public class Interface {
+ public string package_name;
+ public string name;
+ public string purpose;
+ public string description;
++ public Vala.List<Member> methods = new Vala.ArrayList<Member>();
++ public Vala.List<Member> signals = new Vala.ArrayList<Member>();
+
+ public Interface (string package_name,
+ string name,
+ string purpose = "",
+ string description = "")
+ {
+ this.package_name = package_name;
+ this.name = name;
+ this.purpose = purpose;
+ this.description = description;
+ }
+
+ public void add_method (Member member) {
+ member.iface = this;
+ methods.add (member);
+ }
+
+ public void add_signal (Member member) {
+ member.iface = this;
+ signals.add (member);
+ }
+
+ public string get_docbook_id () {
+ return to_docbook_id (name);
+ }
+
+ public bool write (Settings settings, ErrorReporter reporter) {
+ var xml_dir = Path.build_filename (settings.path, "xml");
+ DirUtils.create_with_parents (xml_dir, 0777);
+
+ var xml_file = Path.build_filename (xml_dir,
+ "%s.xml".printf (to_docbook_id (name)));
+ var writer = new TextWriter (xml_file, "w");
+ if (!writer.open ()) {
+ reporter.simple_error ("GtkDoc",
+ "unable to open '%s' for writing", writer.filename);
+ return false;
+ }
+ writer.write_line (to_string (reporter));
+ writer.close ();
+ return true;
+ }
+
+ public string to_string (ErrorReporter reporter) {
+ /* compute minimum indent for methods */
+ var method_indent = 0;
+ foreach (var method in methods) {
+ method_indent = int.max (method_indent, (int)method.name.length);
+ }
+ method_indent += 5;
+
+ /* compute minimum indent for signals */
+ var signal_indent = 0;
+ foreach (var sig in signals) {
+ signal_indent = int.max (signal_indent, (int)sig.name.length);
+ }
+ signal_indent += 5;
+
+ var builder = new StringBuilder ();
+ var docbook_id = get_docbook_id ();
+
+ builder.append ("<?xml version=\"1.0\"?><!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.3//EN\" \"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd\"");
+ builder.append_printf ("""
+ [<!ENTITY %% local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">]>
+ <refentry id="docs-%s">
+ <refmeta>
+ <refentrytitle role="top_of_page" id="docs-%s.top_of_page">%s</refentrytitle>
+ <manvolnum>3</manvolnum>
+ <refmiscinfo>
+ %s D-Bus API
+ </refmiscinfo>
+ </refmeta>
+ <refnamediv>
+ <refname>%s</refname>
+ <refpurpose>%s</refpurpose>
+ </refnamediv>""",
+ docbook_id,
+ docbook_id,
+ name,
+ package_name.up (),
+ name,
+ purpose ?? "");
+
+ /*
+ * Methods
+ */
+ if (methods.size > 0) {
+ builder.append_printf ("""
+ <refsynopsisdiv id="docs-%s.synopsis" role="synopsis">
+ <title role="synopsis.title">Methods</title>
+ <synopsis>""", docbook_id);
+ foreach (var method in methods) {
+ builder.append (method.to_string (method_indent, true));
+ }
+ builder.append ("</synopsis></refsynopsisdiv>");
+ }
+
+ /*
+ * Signals
+ */
+ if (signals.size > 0) {
+ builder.append_printf ("""
+ <refsynopsisdiv id="docs-%s.signals" role="signal_proto">
+ <title role="signal_proto.title">Signals</title>
+ <synopsis>""", docbook_id);
+ foreach (var sig in signals) {
+ builder.append (sig.to_string (signal_indent, true));
+ }
+ builder.append ("</synopsis></refsynopsisdiv>");
+ }
+
+ /*
+ * Description
+ */
+ builder.append_printf ("""
+ <refsect1 id="docs-%s.description" role="desc">
+ <title role="desc.title">Description</title>
+ %s
+ </refsect1>""", docbook_id, description);
+
+ /*
+ * Methods details
+ */
+ if (methods.size > 0) {
+ builder.append_printf ("""
+ <refsect1 id="docs-%s.details" role="details">
+ <title role="details.title">Details</title>""", docbook_id);
+
+ foreach (var method in methods) {
+ builder.append_printf ("""
+ <refsect2 id="%s-%s" role="function">
+ <title>%s ()</title>
+ <programlisting>%s
+ </programlisting>
+ %s
+ </refsect2>""",
+ docbook_id,
+ method.get_docbook_id (),
+ method.name,
+ method.to_string (method_indent, false),
+ method.comment != null ? method.comment.to_docbook (reporter) : "");
+ }
+
+ builder.append ("</refsect1>");
+ }
+
+ /*
+ * Signals details
+ */
+ if (signals.size > 0) {
+ builder.append_printf ("""
+ <refsect1 id="docs-%s.signal-details" role="signals">
+ <title role="signals.title">Signal Details</title>""", docbook_id);
+
+ foreach (var sig in signals) {
+ builder.append_printf ("""
+ <refsect2 id="%s-%s" role="signal">
+ <title>The <literal>%s</literal> signal</title>
+ <programlisting>%s
+ </programlisting>
+ %s
+ </refsect2>""",
+ docbook_id,
+ sig.get_docbook_id (),
+ sig.name,
+ sig.to_string (signal_indent, false),
+ sig.comment != null ? sig.comment.to_docbook (reporter) : "");
+ }
+
+ builder.append ("</refsect1>");
+ }
+
+ builder.append ("</refentry>");
+ return builder.str;
+ }
+ }
+ }
--- /dev/null
- public Gee.List<Header> headers = new Gee.LinkedList<Header> ();
+ /* gcomment.vala
+ *
+ * Copyright (C) 2010 Luca Bruno
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Luca Bruno <lethalman88@gmail.com>
+ */
+
+ public class Gtkdoc.Header {
+ public string name;
+ public string[]? annotations;
+ public string? value;
+ public double pos;
+ public bool block;
+
+ public Header (string name, string? value = null, double pos = double.MAX, bool block = true) {
+ this.name = name;
+ this.value = value;
+ this.pos = pos;
+ this.block = block;
+ }
+
+ public int cmp (Header header) {
+ if (pos > header.pos) {
+ return 1;
+ } else if (pos < header.pos) {
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ public class Gtkdoc.GComment {
+ public string symbol;
+ public string[] symbol_annotations;
- public Gee.List<Header> versioning = new Gee.LinkedList<Header> ();
++ public Vala.List<Header> headers = new Vala.ArrayList<Header> ();
+ public bool short_description;
+ public string brief_comment;
+ public string long_comment;
+ public string returns;
+ public string[] returns_annotations;
++ public Vala.List<Header> versioning = new Vala.ArrayList<Header> ();
+ public string[] see_also;
+ public bool is_section;
+
+ public string to_string () {
+ var builder = new StringBuilder ();
+
+ builder.append_printf ("/**\n * %s", (is_section ? "SECTION:%s" : "%s:").printf (symbol));
+ if (symbol_annotations != null && symbol_annotations.length > 0) {
+ foreach (var annotation in symbol_annotations) {
+ builder.append_printf (" (%s)", annotation);
+ }
+ }
+
+ if (short_description && brief_comment != null) {
+ builder.append_printf ("\n * @short_description: %s", commentize (brief_comment));
+ }
+
+ headers.sort ((CompareDataFunc) Header.cmp);
+ foreach (var header in headers) {
+ builder.append_printf ("\n * @%s:", header.name);
+ if (header.annotations != null && header.annotations.length > 0) {
+ foreach (var annotation in header.annotations) {
+ builder.append_printf (" (%s)", annotation);
+ }
+ builder.append_c (':');
+ }
+
+ if (header.value != null) {
+ builder.append_c (' ');
+ builder.append (commentize (header.value));
+ }
+ }
+
+ if (!short_description && brief_comment != null) {
+ builder.append_printf ("\n * \n * %s", commentize (brief_comment));
+ }
+ if (long_comment != null) {
+ builder.append_printf ("\n * \n * %s", commentize (long_comment));
+ }
+
+ if (see_also.length > 0) {
+ builder.append_printf ("\n * \n * <emphasis>See also</emphasis>: %s", string.joinv (", ", see_also));
+ }
+
+ if (returns != null || returns_annotations.length > 0) {
+ builder.append ("\n * \n * Returns:");
+ if (returns_annotations != null) {
+ foreach (var annotation in returns_annotations) {
+ builder.append_printf (" (%s)", annotation);
+ }
+
+ if (returns_annotations.length > 0) {
+ builder.append_c (':');
+ }
+ }
+ builder.append_c (' ');
+
+ if (returns != null) {
+ builder.append (commentize (returns));
+ }
+ }
+
+ if (versioning.size > 0) {
+ builder.append ("\n *");
+ foreach (var version in versioning) {
+ builder.append_printf ("\n * %s:", version.name);
+ if (version.value != null) {
+ builder.append_printf (" %s", commentize (version.value));
+ }
+ }
+ }
+
+ builder.append ("\n */");
+ return builder.str;
+ }
+
+ public string to_docbook (Valadoc.ErrorReporter reporter) {
+ /*
+ * FIXME: this is not how it should be.
+ * The real solution is to create a comment like gtkdoc-mkdb does.
+ * This implies replacing the work of gtkdoc-mkdb and have a more accurate management of headers,
+ * (i.e. differentiate between parameters, short_description, see_also, etc.).
+ *
+ * For now we'll assume all headers are parameters.
+ * This is enough for a manually generated xml file only for D-Bus API.
+ *
+ * In other words, we are converting C/gtkdoc comment to a docbook comment.
+ */
+
+ string? deprecated = null;
+ string? since = null;
+ foreach (var header in versioning) {
+ if (header.name == "Deprecated") {
+ deprecated = header.value;
+ } else if (header.name == "Since") {
+ since = header.value;
+ } else {
+ reporter.simple_warning ("GtkDoc", "Unknown versioning tag '%s'", header.name);
+ }
+ }
+
+ var builder = new StringBuilder ();
+ if (deprecated != null) {
+ builder.append_printf ("""<warning><para><literal>%s</literal> is deprecated and should not be used in newly-written code. %s</para></warning>""", symbol, deprecated);
+ }
+
+ if (brief_comment != null) {
+ builder.append_printf ("<para>%s</para>", brief_comment);
+ }
+ if (long_comment != null) {
+ builder.append (long_comment);
+ }
+
+ headers.sort ((CompareDataFunc) Header.cmp);
+ if (headers.size > 0 || returns != null) {
+ builder.append ("""<variablelist role="params">""");
+ foreach (var header in headers) {
+ builder.append_printf ("""<varlistentry><term><parameter>%s</parameter> :</term>
+ <listitem><simpara> %s </simpara></listitem></varlistentry>""",
+ header.name, header.value);
+ }
+ if (returns != null) {
+ builder.append_printf ("""<varlistentry><term><emphasis>Returns</emphasis> :</term>
+ <listitem><simpara> %s </simpara></listitem></varlistentry>""", returns);
+ }
+ builder.append ("</variablelist>");
+ }
+
+ if (since != null) {
+ builder.append_printf ("""<para role="since">Since %s</para>""", since);
+ }
+
+ return builder.str;
+ }
+ }
+
--- /dev/null
- public Gee.List<GComment> comments;
- public Gee.List<string> section_lines;
- public Gee.List<string> standard_section_lines;
- public Gee.List<string> private_section_lines;
+ /* generator.vala
+ *
+ * Copyright (C) 2010 Luca Bruno
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Luca Bruno <lethalman88@gmail.com>
+ */
+
+ using Valadoc;
+ using Valadoc.Api;
+ using Valadoc.Content;
+
+ public class Gtkdoc.Generator : Api.Visitor {
+ class FileData {
+ public string filename;
+ public string title;
+ public GComment section_comment;
- public Gee.List<DBus.Interface> dbus_interfaces = new Gee.LinkedList<DBus.Interface>();
++ public Vala.List<GComment> comments;
++ public Vala.List<string> section_lines;
++ public Vala.List<string> standard_section_lines;
++ public Vala.List<string> private_section_lines;
+
+ public void register_section_line (string? line) {
+ if (line != null) {
+ section_lines.add (line);
+ }
+ }
+
+ public void register_standard_section_line (string? line) {
+ if (line != null) {
+ standard_section_lines.add (line);
+ }
+ }
+
+ public void register_private_section_line (string? line) {
+ if (line != null) {
+ private_section_lines.add (line);
+ }
+ }
+ }
+
- private Gee.Map<string, FileData> files_data = new Gee.HashMap<string, FileData>();
++ public Vala.List<DBus.Interface> dbus_interfaces = new Vala.ArrayList<DBus.Interface>();
+
+ private ErrorReporter reporter;
+ private Settings settings;
- private Gee.List<Header> current_headers;
++ private Vala.Map<string, FileData> files_data = new Vala.HashMap<string, FileData> (str_hash, str_equal);
+ private string current_cname;
- foreach (var file_data in files_data.values) {
++ private Vala.List<Header> current_headers;
+ private Api.Tree current_tree;
+ private Class current_class;
+ private Method current_method;
+ private Delegate current_delegate;
+ private Api.Signal current_signal;
+ private DBus.Interface current_dbus_interface;
+ private DBus.Member current_dbus_member;
+
+ private string combine_inline_docs (string? str1, string? str2) {
+ StringBuilder builder = new StringBuilder ();
+ if (str1 != null) {
+ builder.append (str1._chomp ());
+ }
+
+ if (builder.len > 0 && builder.str[builder.len - 1] != '.' && str2 != null) {
+ builder.append (". ");
+ }
+
+ if (str2 != null) {
+ builder.append_c (' ');
+ builder.append (str2);
+ }
+
+ return (owned) builder.str;
+ }
+
+ private Api.Node? current_method_or_delegate {
+ get {
+ if (current_method != null) {
+ return current_method;
+ } else if (current_delegate != null) {
+ return current_delegate;
+ }
+ return null;
+ }
+ }
+
+ public bool execute (Settings settings, Api.Tree tree, ErrorReporter reporter) {
+ this.settings = settings;
+ this.reporter = reporter;
+ this.current_tree = tree;
+ tree.accept (this);
+ var code_dir = Path.build_filename (settings.path, "ccomments");
+ var sections = Path.build_filename (settings.path, "%s-sections.txt".printf (settings.pkg_name));
+ DirUtils.create_with_parents (code_dir, 0777);
+
+ var sections_writer = new TextWriter (sections, "a");
+ if (!sections_writer.open ()) {
+ reporter.simple_error ("GtkDoc", "unable to open '%s' for writing", sections_writer.filename);
+ return false;
+ }
+
- public Gee.Set<string> get_filenames () {
- return files_data.keys.read_only_view;
++ foreach (var file_data in files_data.get_values ()) {
+ // C comments
+ var basename = get_section (file_data.filename);
+ var cwriter = new TextWriter (Path.build_filename (code_dir, "%s.c".printf (basename)), "w");
+
+ if (!cwriter.open ()) {
+ reporter.simple_error ("GtkDoc", "unable to open '%s' for writing", cwriter.filename);
+ return false;
+ }
+
+ // Gtkdoc SECTION
+ if (file_data.section_comment != null) {
+ cwriter.write_line (file_data.section_comment.to_string ());
+ }
+
+ foreach (var comment in file_data.comments) {
+ cwriter.write_line (comment.to_string ());
+ }
+ cwriter.close ();
+
+ // sections
+ sections_writer.write_line ("<SECTION>");
+ sections_writer.write_line ("<FILE>%s</FILE>".printf (basename));
+ if (file_data.title != null) {
+ sections_writer.write_line ("<TITLE>%s</TITLE>".printf (file_data.title));
+ }
+
+ foreach (var section_line in file_data.section_lines) {
+ sections_writer.write_line (section_line);
+ }
+
+ if (file_data.standard_section_lines.size > 0) {
+ sections_writer.write_line ("<SUBSECTION Standard>");
+
+ foreach (var section_line in file_data.standard_section_lines) {
+ sections_writer.write_line (section_line);
+ }
+ }
+
+ if (file_data.private_section_lines.size > 0) {
+ sections_writer.write_line ("<SUBSECTION Private>");
+
+ foreach (var section_line in file_data.private_section_lines) {
+ sections_writer.write_line (section_line);
+ }
+ }
+
+ sections_writer.write_line ("</SECTION>");
+ }
+ sections_writer.close ();
+
+ return true;
+ }
+
- file_data.comments = new Gee.LinkedList<GComment>();
- file_data.section_lines = new Gee.LinkedList<string>();
- file_data.standard_section_lines = new Gee.LinkedList<string>();
- file_data.private_section_lines = new Gee.LinkedList<string>();
++ public Vala.Set<string> get_filenames () {
++ return files_data.get_keys ();
+ }
+
+ private FileData get_file_data (string filename) {
+ var file_data = files_data[filename];
+ if (file_data == null) {
+ file_data = new FileData ();
+ file_data.filename = filename;
+ file_data.title = null;
+ file_data.section_comment = null;
- private Gee.List<Header> merge_headers (Gee.List<Header> doc_headers,
- Gee.List<Header>? lang_headers)
++ file_data.comments = new Vala.ArrayList<GComment>();
++ file_data.section_lines = new Vala.ArrayList<string>(str_equal);
++ file_data.standard_section_lines = new Vala.ArrayList<string>(str_equal);
++ file_data.private_section_lines = new Vala.ArrayList<string>(str_equal);
+ files_data[filename] = file_data;
+ }
+ return file_data;
+ }
+
- var headers = new Gee.LinkedList<Header>();
++ private Vala.List<Header> merge_headers (Vala.List<Header> doc_headers,
++ Vala.List<Header>? lang_headers)
+ {
+ if (lang_headers == null) {
+ return doc_headers;
+ }
+
- current_headers = new Gee.LinkedList<Header>();
++ var headers = new Vala.ArrayList<Header>();
+
+ foreach (var doc_header in doc_headers) {
+ var header = doc_header;
+ foreach (var lang_header in lang_headers) {
+ if (doc_header.name == lang_header.name) {
+ header.annotations = lang_header.annotations;
+ if (lang_header.value == null) {
+ continue;
+ }
+
+ if (lang_header.block) {
+ header.value += "<para>%s</para>".printf (lang_header.value);
+ } else {
+ header.value = combine_inline_docs (lang_header.value, header.value);
+ }
+ }
+ }
+ headers.add (header);
+ }
+
+ // add remaining headers
+ foreach (var lang_header in lang_headers) {
+ bool found = false;
+
+ foreach (var header in headers) {
+ if (header.name == lang_header.name) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found && lang_header.value != null) {
+ headers.add (lang_header);
+ }
+ }
+ return headers;
+ }
+
+ private void set_section_comment (string filename,
+ string section_name,
+ Content.Comment? comment,
+ string symbol_full_name)
+ {
+ var file_data = get_file_data (filename);
+ if (file_data.title == null) {
+ file_data.title = section_name;
+ }
+ if (comment == null) {
+ return;
+ }
+ if (file_data.section_comment != null) {
+ // already have a section comment
+ return;
+ }
+
+ var gcomment = create_gcomment (get_section (filename), comment);
+ gcomment.is_section = true;
+ gcomment.short_description = true;
+ file_data.section_comment = gcomment;
+
+ /* gtk-doc will warn about missing long descriptions (e.g.
+ * “alias-details:Long_Description” in *-undocumented.txt), so
+ * forward that as a Valadoc warning so that it doesn’t get lost
+ * in the gtk-doc output files. */
+ if (gcomment.long_comment == null || gcomment.long_comment == "") {
+ reporter.simple_warning ("GtkDoc", "Missing long description in the documentation for ‘%s’ which forms gtk-doc section ‘%s’.",
+ symbol_full_name,
+ section_name);
+ }
+ }
+
+ private GComment create_gcomment (string symbol,
+ Content.Comment? comment,
+ string[]? returns_annotations = null,
+ bool is_dbus = false)
+ {
+ var converter = new Gtkdoc.CommentConverter (reporter, current_method_or_delegate);
+
+ if (comment != null) {
+ converter.convert (comment, is_dbus);
+ }
+
+ var gcomment = new GComment ();
+ gcomment.symbol = symbol;
+ gcomment.returns = converter.returns;
+ gcomment.returns_annotations = returns_annotations;
+ gcomment.see_also = converter.see_also;
+
+ gcomment.brief_comment = converter.brief_comment;
+ gcomment.long_comment = converter.long_comment;
+
+ gcomment.headers.add_all (merge_headers (converter.parameters, current_headers));
+ gcomment.versioning.add_all (converter.versioning);
+ return gcomment;
+ }
+
+ private GComment add_comment (string filename, string symbol, Content.Comment? comment = null) {
+ var file_data = get_file_data (filename);
+ var gcomment = create_gcomment (symbol, comment);
+ file_data.comments.add (gcomment);
+ return gcomment;
+ }
+
+ private GComment add_symbol (string filename,
+ string cname,
+ Content.Comment? comment = null,
+ string? symbol = null,
+ string[]? returns_annotations = null)
+ {
+ var file_data = get_file_data (filename);
+
+ file_data.register_section_line (cname);
+
+ var gcomment = create_gcomment (symbol ?? cname, comment, returns_annotations);
+ file_data.comments.add (gcomment);
+ return gcomment;
+ }
+
+ private Header? add_custom_header (string name,
+ string? comment,
+ string[]? annotations = null,
+ double pos = double.MAX,
+ bool block = true)
+ {
+ if (comment == null && annotations == null) {
+ return null;
+ }
+
+ var header = new Header (name, comment, pos, block);
+ header.annotations = annotations;
+ current_headers.add (header);
+ return header;
+ }
+
+ private Header? remove_custom_header (string name) {
+ var it = current_headers.iterator();
+ while (it.next ()) {
+ var header = it.@get ();
+ if (header.name == name) {
+ it.remove ();
+ return header;
+ }
+ }
+ return null;
+ }
+
+ private Header? add_header (string name,
+ Content.Comment? comment,
+ string[]? annotations = null,
+ double pos = double.MAX)
+ {
+ if (comment == null && annotations == null) {
+ return null;
+ }
+
+ var converter = new Gtkdoc.CommentConverter (reporter, current_method_or_delegate);
+ var header = new Header (name);
+ header.pos = pos;
+
+ if (comment != null) {
+ converter.convert (comment);
+ if (converter.brief_comment != null) {
+ header.value = converter.brief_comment;
+ if (converter.long_comment != null) {
+ header.value += converter.long_comment;
+ }
+ }
+ }
+
+ header.annotations = annotations;
+ current_headers.add (header);
+ return header;
+ }
+
+ public override void visit_tree (Api.Tree tree) {
+ tree.accept_children (this);
+ }
+
+ public override void visit_package (Api.Package package) {
+ /* we are not (yet?) interested in external packages */
+ if (package.is_package) {
+ return;
+ }
+
+ package.accept_all_children (this);
+ }
+
+ public override void visit_namespace (Api.Namespace ns) {
+ if (ns.get_filename () != null && ns.documentation != null) {
+ set_section_comment (ns.get_filename (),
+ get_section (ns.get_filename ()),
+ ns.documentation,
+ ns.get_full_name ());
+ }
+
+ ns.accept_all_children (this);
+ }
+
+ public override void visit_interface (Api.Interface iface) {
+ var old_cname = current_cname;
+ var old_headers = current_headers;
+ var old_dbus_interface = current_dbus_interface;
+ current_cname = iface.get_cname ();
- current_headers = new Gee.LinkedList<Header>();
++ current_headers = new Vala.ArrayList<Header>();
+ current_dbus_interface = null;
+
+ if (iface.get_dbus_name () != null) {
+ current_dbus_interface = new DBus.Interface (settings.pkg_name, iface.get_dbus_name ());
+ }
+
+ iface.accept_all_children (this);
+
+ var gcomment = add_symbol (iface.get_filename(), iface.get_cname(), iface.documentation, null);
+ set_section_comment (iface.get_filename(),
+ iface.get_cname(),
+ iface.documentation,
+ iface.get_full_name ());
+
+ if (current_dbus_interface != null) {
+ current_dbus_interface.write (settings, reporter);
+ dbus_interfaces.add (current_dbus_interface);
+ }
+
+ // Handle attributes for things like deprecation.
+ process_attributes (iface, gcomment);
+
+ // Interface struct
+ current_headers.clear ();
+
+ var abstract_methods = iface.get_children_by_types ({NodeType.METHOD}, false);
+ foreach (var m in abstract_methods) {
+ // List all protected methods, even if they're not marked as browsable
+ if (m.is_browsable (settings) || ((Symbol) m).is_protected) {
+ visit_abstract_method ((Api.Method) m);
+ }
+ }
+
+ var abstract_properties = iface.get_children_by_types ({NodeType.PROPERTY}, false);
+ foreach (var prop in abstract_properties) {
+ // List all protected properties, even if they're not marked as browsable
+ if (prop.is_browsable (settings) || ((Symbol) prop).is_protected) {
+ visit_abstract_property ((Api.Property) prop);
+ }
+ }
+
+ add_custom_header ("parent_iface", "the parent interface structure");
+ if (iface.get_attribute ("GenericAccessors") != null) {
+ var type_parameters = iface.get_children_by_type (NodeType.TYPE_PARAMETER, false);
+ foreach (Api.Node _type in type_parameters) {
+ var type = _type as Api.TypeParameter;
+ string type_name_down = type.name.down ();
+ add_custom_header ("get_%s_type".printf (type_name_down),
+ "The #GType for %s".printf (type_name_down));
+ add_custom_header ("get_%s_dup_func".printf (type_name_down),
+ "A dup function for #%sIface.get_%s_type()".printf (iface.get_cname (), type_name_down));
+ add_custom_header ("get_%s_destroy_func".printf (type_name_down),
+ "A destroy function for #%sIface.get_%s_type()".printf (iface.get_cname (), type_name_down));
+ }
+ }
+ gcomment = add_symbol (iface.get_filename (), iface.get_cname () + "Iface");
+ gcomment.brief_comment = "Interface for creating %s implementations.".printf (get_docbook_link (iface));
+
+ // Standard symbols
+ var file_data = get_file_data (iface.get_filename ());
+
+ file_data.register_standard_section_line (iface.get_type_cast_macro_name ());
+ file_data.register_standard_section_line (iface.get_interface_macro_name ());
+ file_data.register_standard_section_line (iface.get_is_type_macro_name ());
+ file_data.register_standard_section_line (iface.get_type_macro_name ());
+ file_data.register_standard_section_line (iface.get_type_function_name ());
+
+ current_cname = old_cname;
+ current_headers = old_headers;
+ current_dbus_interface = old_dbus_interface;
+ }
+
+ public override void visit_class (Api.Class cl) {
+ var old_cname = current_cname;
+ var old_headers = current_headers;
+ var old_class = current_class;
+ var old_dbus_interface = current_dbus_interface;
+ current_cname = cl.get_cname ();
- current_headers = new Gee.LinkedList<Header>();
++ current_headers = new Vala.ArrayList<Header>();
+ current_class = cl;
+ current_dbus_interface = null;
+
+ if (cl.get_dbus_name () != null) {
+ current_dbus_interface = new DBus.Interface (settings.pkg_name, cl.get_dbus_name ());
+ }
+
+ var gcomment = add_symbol (cl.get_filename(), cl.get_type_id());
+ gcomment.brief_comment = "The type for %s.".printf (get_docbook_link (cl));
+
+ cl.accept_all_children (this);
+
+ add_symbol (cl.get_filename(), cl.get_cname(), cl.documentation, null);
+ set_section_comment (cl.get_filename(), cl.get_cname(), cl.documentation, cl.get_full_name ());
+
+ if (current_dbus_interface != null) {
+ current_dbus_interface.write (settings, reporter);
+ dbus_interfaces.add (current_dbus_interface);
+ }
+
+ // Handle attributes for things like deprecation.
+ process_attributes (cl, gcomment);
+
+ if (cl.is_fundamental && cl.base_type == null) {
+ var filename = cl.get_filename ();
+
+ // ref
+ current_headers.clear ();
+ add_custom_header ("instance", "a %s.".printf (get_docbook_link (cl)));
+ gcomment = add_symbol (filename, cl.get_ref_function_cname ());
+ gcomment.brief_comment = "Increases the reference count of @object.";
+ gcomment.returns = "the same @object";
+
+ // unref
+ current_headers.clear ();
+ add_custom_header ("instance", "a %s.".printf (get_docbook_link (cl)));
+ gcomment = add_symbol (filename, cl.get_unref_function_cname ());
+ gcomment.brief_comment = "Decreases the reference count of @object. When its reference count drops to 0, the object is finalized (i.e. its memory is freed).";
+
+ // param_spec
+ current_headers.clear ();
+ add_custom_header ("name", "canonical name of the property specified");
+ add_custom_header ("nick", "nick name for the property specified");
+ add_custom_header ("blurb", "description of the property specified");
+ add_custom_header ("object_type", "%s derived type of this property"
+ .printf (get_docbook_type_link (cl)));
+ add_custom_header ("flags", "flags for the property specified");
+ gcomment = add_symbol (filename, cl.get_param_spec_function_cname ());
+ gcomment.brief_comment = "Creates a new <link linkend=\"GParamSpecBoxed\"><type>GParamSpecBoxed</type></link> instance specifying a %s derived property."
+ .printf (get_docbook_type_link (cl));
+ gcomment.long_comment = "See <link linkend=\"g-param-spec-internal\"><function>g_param_spec_internal()</function></link> for details on property names.";
+
+ // value_set
+ current_headers.clear ();
+ add_custom_header ("value", "a valid <link linkend=\"GValue\"><type>GValue</type></link> of %s derived type"
+ .printf (get_docbook_type_link (cl)));
+ add_custom_header ("v_object", "object value to be set");
+ gcomment = add_symbol (filename, cl.get_set_value_function_cname ());
+ gcomment.brief_comment = "Set the contents of a %s derived <link linkend=\"GValue\"><type>GValue</type></link> to @v_object."
+ .printf (get_docbook_type_link (cl));
+ gcomment.long_comment = "<link linkend=\"%s\"><function>%s()</function></link> increases the reference count of @v_object (the <link linkend=\"GValue\"><type>GValue</type></link> holds a reference to @v_object). If you do not wish to increase the reference count of the object (i.e. you wish to pass your current reference to the <link linkend=\"GValue\"><type>GValue</type></link> because you no longer need it), use <link linkend=\"%s\"><function>%s()</function></link> instead.
+
+ It is important that your <link linkend=\"GValue\"><type>GValue</type></link> holds a reference to @v_object (either its own, or one it has taken) to ensure that the object won't be destroyed while the <link linkend=\"GValue\"><type>GValue</type></link> still exists)."
+ .printf (to_docbook_id (cl.get_set_value_function_cname ()),
+ cl.get_set_value_function_cname (),
+ to_docbook_id (cl.get_take_value_function_cname ()),
+ cl.get_take_value_function_cname ());
+
+ // value_get
+ current_headers.clear ();
+ add_custom_header ("value", "a valid <link linkend=\"GValue\"><type>GValue</type></link> of %s derived type"
+ .printf (get_docbook_type_link (cl)));
+ gcomment = add_symbol (filename, cl.get_get_value_function_cname ());
+ gcomment.brief_comment = "Get the contents of a %s derived <link linkend=\"GValue\"><type>GValue</type></link>."
+ .printf (get_docbook_type_link (cl));
+ gcomment.returns = "object contents of @value";
+
+ // value_take
+ current_headers.clear ();
+ add_custom_header ("value", "a valid <link linkend=\"GValue\"><type>GValue</type></link> of %s derived type"
+ .printf (get_docbook_type_link (cl)));
+ add_custom_header ("v_object", "object value to be set");
+ gcomment = add_symbol (filename, cl.get_take_value_function_cname ());
+ gcomment.brief_comment = "Sets the contents of a %s derived <link linkend=\"GValue\"><type>GValue</type></link> to @v_object and takes over the ownership of the callers reference to @v_object; the caller doesn't have to unref it any more (i.e. the reference count of the object is not increased)."
+ .printf (get_docbook_type_link (cl));
+ gcomment.long_comment = "If you want the GValue to hold its own reference to @v_object, use <link linkend=\"%s\"><function>%s()</function></link> instead."
+ .printf (to_docbook_id (cl.get_set_value_function_cname ()), cl.get_set_value_function_cname ());
+ }
+
+ // Class struct
+ current_headers.clear ();
+
+ var abstract_methods = cl.get_children_by_types ({NodeType.METHOD}, false);
+ foreach (var m in abstract_methods) {
+ // List all protected methods, even if they're not marked as browsable
+ if (m.is_browsable (settings) || ((Symbol) m).is_protected) {
+ visit_abstract_method ((Api.Method) m);
+ }
+ }
+
+ var abstract_properties = cl.get_children_by_types ({NodeType.PROPERTY}, false);
+ foreach (var prop in abstract_properties) {
+ // List all protected properties, even if they're not marked as browsable
+ if (prop.is_browsable (settings) || ((Symbol) prop).is_protected) {
+ visit_abstract_property ((Api.Property) prop);
+ }
+ }
+
+ add_custom_header ("parent_class", "the parent class structure");
+ gcomment = add_symbol (cl.get_filename (), cl.get_cname () + "Class");
+ gcomment.brief_comment = "The class structure for %s. All the fields in this structure are private and should never be accessed directly."
+ .printf (get_docbook_type_link (cl));
+
+ // Standard/Private symbols
+ var file_data = get_file_data (cl.get_filename ());
+
+ file_data.register_standard_section_line (cl.get_is_type_macro_name ());
+ file_data.register_standard_section_line (cl.get_is_class_type_macro_name ());
+ file_data.register_standard_section_line (cl.get_type_cast_macro_name ());
+ file_data.register_standard_section_line (cl.get_class_type_macro_name ());
+ file_data.register_standard_section_line (cl.get_class_macro_name ());
+ file_data.register_standard_section_line (cl.get_type_function_name ());
+
+ file_data.register_private_section_line (cl.get_private_cname ());
+ file_data.register_private_section_line (((cl.nspace.name != null)? cl.nspace.name.down () + "_" : "")
+ + to_lower_case (cl.name)
+ + "_construct");
+
+ current_cname = old_cname;
+ current_headers = old_headers;
+ current_class = old_class;
+ current_dbus_interface = old_dbus_interface;
+ }
+
+ private string[]? create_see_function_array (string?[] functions) {
+ string[] arr = new string[] {};
+ foreach (string? func in functions) {
+ if (func != null) {
+ arr += func + "()";
+ }
+ }
+
+ return (arr.length > 0)? arr : null;
+ }
+
+ public override void visit_struct (Api.Struct st) {
+ var old_cname = current_cname;
+ var old_headers = current_headers;
+ current_cname = st.get_cname ();
- current_headers = new Gee.LinkedList<Header>();
++ current_headers = new Vala.ArrayList<Header>();
+
+ st.accept_all_children (this);
+ var gcomment = add_symbol (st.get_filename(), st.get_cname(), st.documentation);
+
+ // Handle attributes for things like deprecation.
+ process_attributes (st, gcomment);
+
+ current_cname = old_cname;
+ current_headers = old_headers;
+
+ var file_data = get_file_data (st.get_filename ());
+
+ file_data.register_standard_section_line (st.get_type_macro_name ());
+ file_data.register_standard_section_line (st.get_type_function_name ());
+
+ string? dup_function_cname = st.get_dup_function_cname ();
+ string? free_function_cname = st.get_free_function_cname ();
+ string? copy_function_cname = st.get_copy_function_cname ();
+ string? destroy_function_cname = st.get_destroy_function_cname ();
+ if (dup_function_cname != null) {
+ var dup_gcomment = add_symbol (st.get_filename (), dup_function_cname);
+ dup_gcomment.headers.add (new Header ("self",
+ "the instance to duplicate"));
+ if (free_function_cname != null) {
+ dup_gcomment.returns = "a copy of @self, free with %s()"
+ .printf (free_function_cname);
+ } else {
+ dup_gcomment.returns = "a copy of @self";
+ }
+
+ dup_gcomment.brief_comment = "Creates a copy of self.";
+ dup_gcomment.see_also = create_see_function_array ({copy_function_cname,
+ destroy_function_cname,
+ free_function_cname});
+ }
+
+ if (free_function_cname != null) {
+ var free_gcomment = add_symbol (st.get_filename (), free_function_cname);
+ free_gcomment.headers.add (new Header ("self", "the struct to free"));
+ free_gcomment.brief_comment = "Frees the heap-allocated struct.";
+ free_gcomment.see_also = create_see_function_array ({dup_function_cname,
+ copy_function_cname,
+ destroy_function_cname});
+ }
+
+ if (copy_function_cname != null) {
+ var copy_gcomment = add_symbol (st.get_filename (), copy_function_cname);
+ copy_gcomment.headers.add (new Header ("self",
+ "the struct to copy"));
+ if (destroy_function_cname != null) {
+ copy_gcomment.headers.add (new Header ("dest",
+ "a unused struct. Use %s() to free the content."
+ .printf (destroy_function_cname)));
+ } else {
+ copy_gcomment.headers.add (new Header ("dest",
+ "a unused struct."));
+ }
+ copy_gcomment.brief_comment = "Creates a copy of self.";
+ copy_gcomment.see_also = create_see_function_array ({dup_function_cname,
+ destroy_function_cname,
+ free_function_cname});
+ }
+
+ if (destroy_function_cname != null) {
+ var destroy_gcomment = add_symbol (st.get_filename (), destroy_function_cname);
+ destroy_gcomment.headers.add (new Header ("self", "the struct to destroy"));
+ destroy_gcomment.brief_comment = "Frees the content of the struct pointed by @self.";
+ destroy_gcomment.see_also = create_see_function_array ({dup_function_cname,
+ copy_function_cname,
+ free_function_cname});
+ }
+ }
+
+ /**
+ * Visit thrown error domains
+ */
+ private void visit_thrown_error_domain (Api.Node error) {
+ // method throws error
+ Header? param_header = null;
+ foreach (var header in current_headers) {
+ if (header.name == "error") {
+ param_header = header;
+ break;
+ }
+ }
+ var edomain = error as Api.ErrorDomain;
+ if (edomain != null) {
+ if (param_header == null) {
+ add_custom_header ("error",
+ "location to store the error occuring, or %NULL to ignore",
+ {"error-domains %s".printf (edomain.get_cname ())},
+ double.MAX-1);
+ } else {
+ // assume the only annotation is error-domains
+ var annotation = param_header.annotations[0];
+ annotation += " %s".printf (edomain.get_cname ());
+ param_header.annotations[0] = annotation;
+ }
+ } else if (param_header == null) {
+ add_custom_header ("error",
+ "location to store the error occuring, or %NULL to ignore",
+ null,
+ double.MAX - 1);
+ }
+ }
+
+ /**
+ * Visit error domain definitions
+ */
+ public override void visit_error_domain (Api.ErrorDomain edomain) {
+ // error domain definition
+ var old_headers = current_headers;
- current_headers = new Gee.LinkedList<Header>();
++ current_headers = new Vala.ArrayList<Header>();
+
+ edomain.accept_all_children (this);
+ var gcomment = add_symbol (edomain.get_filename(),
+ edomain.get_cname(),
+ edomain.documentation);
+
+ // Handle attributes for things like deprecation.
+ process_attributes (edomain, gcomment);
+
+ // Standard symbols
+ var file_data = get_file_data (edomain.get_filename ());
+
+ file_data.register_standard_section_line (edomain.get_quark_function_name ());
+ file_data.register_standard_section_line (edomain.get_quark_macro_name ());
+
+ current_headers = old_headers;
+ }
+
+ public override void visit_error_code (Api.ErrorCode ecode) {
+ add_header (ecode.get_cname (), ecode.documentation);
+ ecode.accept_all_children (this);
+ }
+
+ public override void visit_enum (Api.Enum en) {
+ var old_headers = current_headers;
- current_headers = new Gee.LinkedList<Header>();
++ current_headers = new Vala.ArrayList<Header>();
+
+ en.accept_all_children (this);
+ var gcomment = add_symbol (en.get_filename(), en.get_cname(), en.documentation);
+
+ // Handle attributes for things like deprecation.
+ process_attributes (en, gcomment);
+
+ // Standard symbols
+ var file_data = get_file_data (en.get_filename ());
+
+ file_data.register_standard_section_line (en.get_type_macro_name ());
+ file_data.register_standard_section_line (en.get_type_function_name ());
+
+ current_headers = old_headers;
+ }
+
+ public override void visit_enum_value (Api.EnumValue eval) {
+ add_header (eval.get_cname (), eval.documentation);
+ eval.accept_all_children (this);
+ }
+
+ private string combine_comments (string? brief, string? @long) {
+ StringBuilder builder = new StringBuilder ();
+ if (brief != null) {
+ builder.append (brief.strip ());
+ }
+
+ string _long = (@long != null)? @long.strip () : "";
+ if (builder.len > 0 && _long != "") {
+ builder.append ("\n\n");
+ }
+
+ if (_long != "") {
+ builder.append (_long);
+ }
+
+ return (owned) builder.str;
+ }
+
+ public override void visit_property (Api.Property prop) {
+ if (prop.is_override
+ || prop.is_private
+ || (!prop.is_abstract && !prop.is_virtual && prop.base_property != null))
+ {
+ return;
+ }
+
+ var gcomment = add_comment (prop.get_filename(), "%s:%s"
+ .printf (current_cname, prop.get_cname ()), prop.documentation);
+ prop.accept_all_children (this);
+
+ Api.TypeParameter type_parameter = prop.property_type.data_type as Api.TypeParameter;
+ string? return_type_link = null;
+ if (type_parameter != null) {
+ if (type_parameter.parent is Api.Class) {
+ return_type_link = "#%s:%s-type".printf (get_cname (prop.parent), type_parameter.name.down ());
+ } else if (type_parameter.parent is Api.Interface
+ && ((Api.Symbol) type_parameter.parent).get_attribute ("GenericAccessors") != null)
+ {
+ return_type_link = "#_%sIface.get_%s_type()"
+ .printf (get_cname (type_parameter.parent), type_parameter.name.down ());
+ }
+ }
+
+ // Handle attributes for things like deprecation.
+ process_attributes (prop, gcomment);
+
+ if (prop.getter != null && !prop.getter.is_private && prop.getter.is_get) {
+ var getter_gcomment = add_symbol (prop.get_filename(), prop.getter.get_cname ());
+ getter_gcomment.headers.add (new Header ("self",
+ "the %s instance to query".printf (get_docbook_link (prop.parent)), 1));
+ getter_gcomment.returns = "the value of the %s property"
+ .printf (get_docbook_link (prop));
+ if (return_type_link != null) {
+ getter_gcomment.returns += " of type " + return_type_link;
+ }
+ getter_gcomment.brief_comment = "Get and return the current value of the %s property."
+ .printf (get_docbook_link (prop));
+ getter_gcomment.long_comment = combine_comments (gcomment.brief_comment,
+ gcomment.long_comment);
+
+ if (prop.property_type != null && prop.property_type.data_type is Api.Array) {
+ var array_type = prop.property_type.data_type;
+ for (uint dim = 1; array_type != null && array_type is Api.Array;
+ dim++, array_type = ((Api.Array) array_type).data_type)
+ {
+ gcomment.headers.add (new Header ("result_length%u".printf (dim),
+ "return location for the length of the property's value"));
+ }
+ }
+
+ /* Copy versioning headers such as deprecation and since lines. */
+ getter_gcomment.versioning = gcomment.versioning;
+ }
+
+ if (prop.setter != null && !prop.setter.is_private && prop.setter.is_set) {
+ var setter_gcomment = add_symbol (prop.get_filename(), prop.setter.get_cname ());
+ setter_gcomment.headers.add (new Header ("self", "the %s instance to modify"
+ .printf (get_docbook_link (prop.parent)), 1));
+ string type_desc = (return_type_link != null)? " of type " + return_type_link : "";
+ setter_gcomment.headers.add (new Header ("value", "the new value of the %s property%s"
+ .printf (get_docbook_link (prop), type_desc), 2));
+ setter_gcomment.brief_comment = "Set the value of the %s property to @value."
+ .printf (get_docbook_link (prop));
+ setter_gcomment.long_comment = combine_comments (gcomment.brief_comment,
+ gcomment.long_comment);
+
+ if (prop.property_type != null && prop.property_type.data_type is Api.Array) {
+ var array_type = prop.property_type.data_type;
+ for (uint dim = 1; array_type != null && array_type is Api.Array;
+ dim++, array_type = ((Api.Array) array_type).data_type)
+ {
+ gcomment.headers.add (new Header ("value_length%u".printf (dim),
+ "length of the property's new value"));
+ }
+ }
+
+ /* Copy versioning headers such as deprecation and since lines. */
+ setter_gcomment.versioning = gcomment.versioning;
+ }
+
+ if (return_type_link != null) {
+ string return_type_desc = "<para>Holds a value from type #%s:%s-type.</para>"
+ .printf (get_cname (prop.parent), type_parameter.name.down ());
+ gcomment.long_comment = combine_inline_docs (return_type_desc, gcomment.long_comment);
+ }
+ }
+
+ public override void visit_field (Api.Field f) {
+ if (f.is_private) {
+ return;
+ }
+
+ if (current_headers == null) {
+ // field not in class/struct/interface
+ var gcomment = add_symbol (f.get_filename(), f.get_cname(), f.documentation);
+ f.accept_all_children (this);
+
+ // Handle attributes for things like deprecation.
+ process_attributes (f, gcomment);
+ } else {
+ add_header (f.get_cname (), f.documentation);
+ f.accept_all_children (this);
+ }
+ }
+
+ public override void visit_constant (Api.Constant c) {
+ var gcomment = add_symbol (c.get_filename(), c.get_cname(), c.documentation);
+ c.accept_all_children (this);
+
+ // Handle attributes for things like deprecation.
+ process_attributes (c, gcomment);
+ }
+
+ public override void visit_delegate (Api.Delegate d) {
+ var old_headers = current_headers;
+ var old_delegate = current_delegate;
- current_headers = new Gee.LinkedList<Header>();
++ current_headers = new Vala.ArrayList<Header>();
+ current_delegate = d;
+
+ d.accept_children ({NodeType.FORMAL_PARAMETER, NodeType.TYPE_PARAMETER}, this);
+ var exceptions = d.get_children_by_types ({NodeType.ERROR_DOMAIN, NodeType.CLASS});
+ foreach (var ex in exceptions) {
+ visit_thrown_error_domain (ex);
+ }
+
+ if (!d.is_static) {
+ add_custom_header ("user_data", "data to pass to the delegate function", {"closure"});
+ }
+
+ var gcomment = add_symbol (d.get_filename(), d.get_cname(), d.documentation);
+ Api.TypeParameter type_parameter = d.return_type.data_type as Api.TypeParameter;
+ if (type_parameter != null) {
+ if (type_parameter.parent is Api.Class) {
+ string return_type_desc = "A value from type #%s:%s-type."
+ .printf (get_cname (d.parent), type_parameter.name.down ());
+ gcomment.returns = combine_inline_docs (return_type_desc, gcomment.returns);
+ } else if (type_parameter.parent is Api.Interface
+ && ((Api.Symbol) type_parameter.parent).get_attribute ("GenericAccessors") != null)
+ {
+ string return_type_desc = "A value from type #_%sIface.get_%s_type()."
+ .printf (get_cname (d.parent), type_parameter.name.down ());
+ gcomment.returns = combine_inline_docs (return_type_desc, gcomment.returns);
+ /*
+ } else if (type_parameter.parent is Api.Struct) {
+ // type not stored & not allowed
+ } else if (type_parameter.parent == d) {
+ // type not available as argument
+ */
+ }
+ }
+
+ // Handle attributes for things like deprecation.
+ process_attributes (d, gcomment);
+
+ current_headers = old_headers;
+ current_delegate = old_delegate;
+ }
+
+ public override void visit_signal (Api.Signal sig) {
+ var old_headers = current_headers;
+ var old_signal = current_signal;
+ var old_dbus_member = current_dbus_member;
- current_headers = new Gee.LinkedList<Header>();
++ current_headers = new Vala.ArrayList<Header>();
+ current_signal = sig;
+ current_dbus_member = null;
+
+ if (current_dbus_interface != null && sig.is_dbus_visible) {
+ current_dbus_member = new DBus.Member (sig.get_dbus_name ());
+ }
+
+ sig.accept_all_children (this);
+
+ var name = sig.get_cname().replace ("_", "-");
+ var gcomment = add_comment (sig.get_filename(), "%s::%s".printf (current_cname, name), sig.documentation);
+ // gtkdoc maps parameters by their ordering, so let's customly add the first parameter
+ gcomment.headers.insert (0, new Header (to_lower_case (((Api.Node)sig.parent).name),
+ "the %s instance that received the signal".printf (get_docbook_link (sig.parent)),
+ 0.1));
+ if (current_dbus_interface != null && sig.is_dbus_visible) {
+ var dbuscomment = create_gcomment (sig.get_dbus_name (), sig.documentation, null, true);
+ current_dbus_member.comment = dbuscomment;
+ current_dbus_interface.add_signal (current_dbus_member);
+ }
+
+ Api.TypeParameter type_parameter = sig.return_type.data_type as Api.TypeParameter;
+ if (type_parameter != null) {
+ if (type_parameter.parent is Api.Class) {
+ string return_type_desc = "A value from type #%s:%s-type."
+ .printf (get_cname (type_parameter.parent), type_parameter.name.down ());
+ gcomment.returns = combine_inline_docs (return_type_desc,
+ gcomment.returns);
+ } else if (type_parameter.parent is Api.Interface
+ && ((Api.Symbol) type_parameter.parent).get_attribute ("GenericAccessors") != null)
+ {
+ string return_type_desc = "A value from type #_%sIface.get_%s_type()."
+ .printf (get_cname (type_parameter.parent), type_parameter.name.down ());
+ gcomment.returns = combine_inline_docs (return_type_desc,
+ gcomment.returns);
+ }
+ }
+
+
+ // Handle attributes for things like deprecation.
+ process_attributes (sig, gcomment);
+
+ current_headers = old_headers;
+ current_signal = old_signal;
+ current_dbus_member = old_dbus_member;
+ }
+
+ public override void visit_method (Api.Method m) {
+ if ((m.is_constructor && current_class != null && current_class.is_abstract)
+ || m.is_override
+ || m.is_private
+ || (!m.is_abstract && !m.is_virtual && m.base_method != null))
+ {
+ return;
+ }
+
+ var annotations = new string[]{};
+
+ if (m.return_type != null) {
+ if (m.return_type.data_type is Api.Array) {
+ annotations += "array length=result_length1";
+ }
+
+ if (m.return_type.is_unowned) {
+ annotations += "transfer none";
+ }
+ }
+
+ var old_headers = current_headers;
+ var old_method = current_method;
+ var old_dbus_member = current_dbus_member;
++ current_headers = new Vala.ArrayList<Header>();
+ current_method = m;
+ current_dbus_member = null;
+
+ if (current_dbus_interface != null && m.is_dbus_visible && !m.is_constructor) {
+ current_dbus_member = new DBus.Member (m.get_dbus_name ());
+ }
+
+ if (!m.is_static && !m.is_constructor) {
+ add_custom_header ("self",
+ "the %s instance".printf (get_docbook_link (m.parent)),
+ null,
+ 0.1);
+ }
+
+ if (m.is_constructor) {
+ // parent type parameters:
+ var type_parameters = ((Api.Node) m.parent).get_children_by_type (NodeType.TYPE_PARAMETER, false);
+ foreach (Api.Node _type in type_parameters) {
+ var type = _type as Api.TypeParameter;
+ string type_name_down = type.name.down ();
+ add_custom_header (type_name_down + "_type",
+ "A #GType");
+ add_custom_header (type_name_down + "_dup_func",
+ "A dup function for @%s_type".printf (type_name_down));
+ add_custom_header (type_name_down + "_destroy_func",
+ "A destroy function for @%s_type".printf (type_name_down));
+ }
+ }
+
+ // type parameters:
+ var type_parameters = m.get_children_by_type (NodeType.TYPE_PARAMETER, false);
+ foreach (Api.Node _type in type_parameters) {
+ var type = _type as Api.TypeParameter;
+ string type_name_down = type.name.down ();
+ add_custom_header (type_name_down + "_type",
+ "The #GType for @%s".printf (type_name_down),
+ null,
+ 0.2);
+ add_custom_header (type_name_down + "_dup_func",
+ "A dup function for @%s_type".printf (type_name_down),
+ null,
+ 0.3);
+ add_custom_header (type_name_down + "_destroy_func",
+ "A destroy function for @%s_type".printf (type_name_down),
+ null,
+ 0.4);
+ }
+
+ m.accept_children ({NodeType.FORMAL_PARAMETER, NodeType.TYPE_PARAMETER}, this);
+ var exceptions = m.get_children_by_types ({NodeType.ERROR_DOMAIN, NodeType.CLASS});
+ foreach (var ex in exceptions) {
+ visit_thrown_error_domain (ex);
+ }
+
+ Header error_header = null;
+ GComment gcomment = null;
+ if (m.is_yields) {
+ add_custom_header ("_callback_",
+ "callback to call when the request is satisfied",
+ {"scope async"});
+ add_custom_header ("_user_data_",
+ "the data to pass to @_callback_ function",
+ {"closure"});
+ // remove error from here, put that in the _finish function
+ error_header = remove_custom_header ("error");
+
+ gcomment = add_symbol (m.get_filename(), m.get_cname (), m.documentation);
+ gcomment.returns = null; // async method has no return value
+ var see_also = gcomment.see_also; // vala bug
+ see_also += get_docbook_link (m, false, true);
+ gcomment.see_also = see_also;
+ } else {
+ gcomment = add_symbol (m.get_filename(),
+ m.get_cname (),
+ m.documentation,
+ null,
+ annotations);
+ }
+
+ // Handle attributes for things like deprecation.
+ process_attributes (m, gcomment);
+
+ remove_custom_header ("self");
+
+ if (current_dbus_interface != null && m.is_dbus_visible && !m.is_constructor) {
+ if (m.return_type != null && m.return_type.data_type != null) {
+ var dresult = new DBus.Parameter (m.get_dbus_result_name (),
+ m.return_type.get_dbus_type_signature (),
+ DBus.Parameter.Direction.OUT);
+ current_dbus_member.add_parameter (dresult);
+ }
+ var dbus_gcomment = create_gcomment (m.get_dbus_name (),
+ m.documentation,
+ null,
+ true);
+ current_dbus_member.comment = dbus_gcomment;
+ current_dbus_interface.add_method (current_dbus_member);
+ }
+
+ current_headers = old_headers;
+ current_method = old_method;
+ current_dbus_member = old_dbus_member;
+
+ string? return_type_desc = null;
+ Api.TypeParameter type_parameter = m.return_type.data_type as Api.TypeParameter;
+ if (type_parameter != null) {
+ if (type_parameter.parent is Api.Class) {
+ return_type_desc = "A value from type #%s:%s-type."
+ .printf (get_cname (m.parent), type_parameter.name.down ());
+ } else if (type_parameter.parent is Api.Interface
+ && ((Api.Symbol) type_parameter.parent).get_attribute ("GenericAccessors") != null)
+ {
+ return_type_desc = "A value from type #_%sIface.get_%s_type()."
+ .printf (get_cname (m.parent), type_parameter.name.down ());
+ } else if (type_parameter.parent is Api.Struct) {
+ // type not stored
+ } else if (type_parameter.parent == m) {
+ return_type_desc = "value from type @%s_type.".printf (type_parameter.name.down ());
+ }
+ }
+
+ if (m.is_yields) {
+ var finish_gcomment = add_symbol (m.get_filename(),
+ m.get_finish_function_cname (),
+ m.documentation);
+ finish_gcomment.headers.clear ();
+
+ if (!m.is_static) {
+ finish_gcomment.headers.add (new Header ("self",
+ "the %s instance".printf (get_docbook_link (m.parent))));
+ }
+ finish_gcomment.headers.add (new Header ("_res_",
+ "a <link linkend=\"GAsyncResult\"><type>GAsyncResult</type></link>"));
+ if (error_header != null) {
+ finish_gcomment.headers.add (error_header);
+ }
+
+ var see_also = finish_gcomment.see_also; // vala bug
+ see_also += get_docbook_link (m);
+ finish_gcomment.see_also = see_also;
+
+ if (return_type_desc != null) {
+ finish_gcomment.returns = combine_inline_docs (return_type_desc, finish_gcomment.returns);
+ }
+ } else {
+ if (return_type_desc != null) {
+ gcomment.returns = combine_inline_docs (return_type_desc, gcomment.returns);
+ }
+ }
+
+
+ if (m.is_constructor && !m.get_cname ().has_suffix ("_new")) {
+ // Hide secondary _construct methods from the documentation
+ // (the primary _construct method is hidden in visit_class())
+ var file_data = get_file_data (m.get_filename ());
+ file_data.private_section_lines.add (m.get_cname ().replace ("_new", "_construct"));
+ }
+ }
+
+ /**
+ * Visit abstract methods
+ */
+ private void visit_abstract_method (Api.Method m) {
+ if (!m.is_abstract && !m.is_virtual) {
+ return;
+ }
+
+ if (!m.is_private && !m.is_protected && !m.is_internal) {
+ add_custom_header (m.name, "virtual method called by %s"
+ .printf (get_docbook_link (m)));
+
+ if (m.is_yields) {
+ add_custom_header (m.name + "_finish", "asynchronous finish function for <structfield>%s</structfield>, called by %s"
+ .printf (m.name, get_docbook_link (m)));
+ }
+ } else {
+ add_custom_header (m.name, "virtual method used internally");
+
+ if (m.is_yields) {
+ add_custom_header (m.name + "_finish", "asynchronous finish function used internally");
+ }
+ }
+ }
+
+ /**
+ * Visit abstract properties
+ */
+ private void visit_abstract_property (Api.Property prop) {
+ if (!prop.is_abstract && !prop.is_virtual) {
+ return;
+ }
+
+ if (prop.getter != null && !prop.getter.is_private && !prop.getter.is_internal && prop.getter.is_get) {
+ add_custom_header ("get_" + prop.name, "getter method for the abstract property %s"
+ .printf (get_docbook_link (prop)));
+ }
+
+ if (prop.setter != null && !prop.setter.is_private && !prop.setter.is_internal && prop.setter.is_set && !prop.setter.is_construct) {
+ add_custom_header ("set_" + prop.name, "setter method for the abstract property %s"
+ .printf (get_docbook_link (prop)));
+ }
+ }
+
+ public override void visit_formal_parameter (Api.FormalParameter param) {
+ var param_name = param.name ?? "...";
+ var annotations = new string[]{};
+ var direction = "in";
+
+ // Avoid "Parameter description for * is missing" warnings
+ add_custom_header (param_name, " ", null, double.MAX, false);
+
+ if (param.is_out) {
+ direction = "out";
+ } else if (param.is_ref) {
+ direction = "inout";
+ }
+ annotations += direction;
+
+ TypeParameter type_parameter = param.parameter_type.data_type as TypeParameter;
+ if (type_parameter != null) {
+ if (type_parameter.parent is Api.Class) {
+ add_custom_header (param_name, "A parameter from type #%s:%s-type."
+ .printf (get_cname (type_parameter.parent), type_parameter.name.down ()), null, double.MAX, false);
+ } else if (type_parameter.parent is Api.Interface && ((Api.Symbol) type_parameter.parent)
+ .get_attribute ("GenericAccessors") != null) {
+ add_custom_header (param_name, "A parameter from type #_%sIface.get_%s_type()."
+ .printf (get_cname (type_parameter.parent), type_parameter.name.down ()), null, double.MAX, false);
+ } else if (type_parameter.parent is Api.Struct) {
+ // type not stored
+ } else if (type_parameter.parent is Method) {
+ add_custom_header (param_name, "A parameter from type @%s_type."
+ .printf (type_parameter.name.down ()), null, double.MAX, false);
+ }
+ }
+
+ if (param.parameter_type.is_nullable) {
+ annotations += "allow-none";
+ }
+
+ if (param.parameter_type.is_owned
+ && !(param.parameter_type.data_type is Api.Delegate))
+ {
+ annotations += "transfer full";
+ }
+
+ if (param.parameter_type.data_type is Api.Array) {
+ annotations += "array length=%s_length1".printf (param_name);
+ add_custom_header ("%s_length1".printf (param_name),
+ "length of the @%s array".printf (param_name),
+ null,
+ get_parameter_pos (current_method_or_delegate, param_name)+0.1);
+ }
+
+ if (!param.ellipsis && param.parameter_type.data_type != null
+ && get_cname (param.parameter_type.data_type) == "GError")
+ {
+ annotations += "not-error";
+ }
+
+ if (current_signal != null && param.documentation == null) {
+ // gtkdoc writes arg0, arg1 which is ugly. As a workaround, we always add an header for them.
+ add_custom_header (param_name, "", null);
+ } else {
+ add_header (param_name, param.documentation, annotations,
+ get_parameter_pos (current_method_or_delegate, param_name));
+ }
+
+ if (param.parameter_type.data_type is Api.Delegate) {
+ add_custom_header ("%s_target".printf (param_name), "user data to pass to @%s".printf (param_name),
+ {"allow-none", "closure"}, get_parameter_pos (current_method_or_delegate, param_name)+0.1);
+ if (param.parameter_type.is_owned) {
+ add_custom_header ("%s_target_destroy_notify".printf (param_name),
+ "function to call when @%s_target is no longer needed".printf (param_name), {"allow-none"},
+ get_parameter_pos (current_method_or_delegate, param_name)+0.2);
+ }
+ }
+
+ if (current_dbus_member != null) {
+ var ddirection = DBus.Parameter.Direction.IN;
+ if (current_signal != null) {
+ ddirection = DBus.Parameter.Direction.NONE;
+ } else if (param.is_out) {
+ ddirection = DBus.Parameter.Direction.OUT;
+ }
+ var dparam = new DBus.Parameter (param_name,
+ param.parameter_type.get_dbus_type_signature (),
+ ddirection);
+ current_dbus_member.add_parameter (dparam);
+ }
+ param.accept_all_children (this);
+ }
+
+ private void process_attributes (Symbol sym, GComment gcomment) {
+ // Handle the ‘Deprecated’ attribute.
+ if (sym.is_deprecated) {
+ Attribute? version;
+ Attribute? deprecated;
+ AttributeArgument? deprecated_since;
+ AttributeArgument? replacement;
+ if ((version = sym.get_attribute ("Version")) != null) {
+ deprecated_since = version.get_argument ("deprecated_since");
+ replacement = version.get_argument ("replacement");
+ } else if ((deprecated = sym.get_attribute ("Deprecated")) != null) {
+ deprecated_since = deprecated.get_argument ("since");
+ replacement = deprecated.get_argument ("replacement");
+ } else {
+ assert_not_reached ();
+ }
+
+ string? since = null;
+ if (deprecated_since != null) {
+ since = deprecated_since.value;
+
+ // Strip surrounding quotation marks.
+ if (since.has_prefix ("\"")) {
+ since = since[1:since.length - 1];
+ }
+ if (since.has_suffix ("\"")) {
+ since = since[0:-1];
+ }
+ }
+
+ string? replacement_symbol_name = null;
+ Api.Node? replacement_symbol = null;
+
+ if (replacement != null) {
+ replacement_symbol_name = replacement.value;
+
+ // Strip surrounding quotation marks.
+ if (replacement_symbol_name.has_prefix ("\"")) {
+ replacement_symbol_name = replacement_symbol_name[1:replacement_symbol_name.length - 1];
+ }
+ if (replacement_symbol_name.has_suffix ("\"")) {
+ replacement_symbol_name = replacement_symbol_name[0:-1];
+ }
+
+ // Strip any trailing brackets.
+ if (replacement_symbol_name.has_suffix ("()")) {
+ replacement_symbol_name = replacement_symbol_name[0:-2];
+ }
+
+ replacement_symbol = current_tree.search_symbol_str (sym,
+ replacement_symbol_name);
+ }
+
+ if (replacement != null && replacement_symbol == null) {
+ reporter.simple_warning ("GtkDoc", "Couldn’t resolve replacement symbol ‘%s’ for ‘Deprecated’ attribute on %s.",
+ replacement_symbol_name,
+ sym.get_full_name ());
+ }
+
+ var deprecation_string = "No replacement specified.";
+
+ if (since != null && replacement_symbol != null) {
+ deprecation_string = "%s: Replaced by %s.".printf (since, get_gtkdoc_link (replacement_symbol));
+ } else if (since != null && replacement_symbol == null) {
+ deprecation_string = "%s: No replacement specified.".printf (since);
+ } else if (since == null && replacement_symbol != null) {
+ deprecation_string = "Replaced by %s.".printf (get_gtkdoc_link (replacement_symbol));
+ } else {
+ reporter.simple_warning ("GtkDoc", "Missing ‘since’ and ‘replacement’ arguments to ‘Deprecated’ attribute on %s.",
+ sym.get_full_name ());
+ }
+
+ gcomment.versioning.add (new Header ("Deprecated", deprecation_string));
+ }
+ }
+ }
--- /dev/null
- -I $(top_builddir)/src/libvaladoc/ \
++include $(top_srcdir)/Makefile.common
++
+ NULL =
+
+ AM_CFLAGS = \
+ -DPACKAGE_ICONDIR=\"$(datadir)/valadoc/icons/\" \
- $(LIBGEE_CFLAGS) \
++ -I$(top_srcdir)/gee/ \
++ -I$(top_srcdir)/libvaladoc/ \
+ $(GLIB_CFLAGS) \
- -g \
- -w \
- $(NULL)
-
-AM_VALAFLAGS = \
- $(VALAFLAGS) \
- --vapidir $(top_srcdir)/src/vapi \
- --vapidir $(top_builddir)/src/libvaladoc \
- --basedir $(srcdir) \
- --directory $(builddir) \
- -C \
- -g \
+ $(LIBGVC_CFLAGS) \
-nodist_libdoclet_la_SOURCES = \
+ $(NULL)
+
+ BUILT_SOURCES = libdoclet.vala.stamp
+
+ doclet_LTLIBRARIES = libdoclet.la
+
+ docletdir = $(libdir)/valadoc/doclets/html
+
+ libdoclet_la_LDFLAGS = -module -avoid-version -no-undefined
+
+ libdoclet_la_VALASOURCES = \
+ doclet.vala \
+ $(NULL)
+
-libdoclet.vala.stamp: $(libdoclet_la_VALASOURCES) Makefile
- $(VALAC) \
- $(AM_VALAFLAGS) \
- --pkg gee-0.8 \
- --pkg valadoc-1.0 \
++libdoclet_la_SOURCES = \
++ libdoclet.vala.stamp \
+ $(libdoclet_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
- $(top_builddir)/src/libvaladoc/libvaladoc.la \
++libdoclet.vala.stamp: $(libdoclet_la_VALASOURCES)
++ $(VALA_V)$(VALAC) \
++ $(VALAFLAGS) \
++ -C \
++ --vapidir $(top_srcdir)/vala \
++ --vapidir $(top_srcdir)/vapi \
++ --vapidir $(top_srcdir)/libvaladoc --pkg valadoc@PACKAGE_SUFFIX@ \
+ $(filter %.vala %.c,$^)
+ touch $@
+
+ libdoclet_la_LIBADD = \
- $(LIBGEE_LIBS) \
++ $(top_builddir)/libvaladoc/libvaladoc@PACKAGE_SUFFIX@.la \
+ $(GLIB_LIBS) \
-CLEANFILES = \
- $(BUILT_SOURCES) \
- $(nodist_libdoclet_la_SOURCES) \
+ $(NULL)
+
+ EXTRA_DIST = \
+ $(libdoclet_la_VALASOURCES) \
++ libdoclet.vala.stamp \
+ $(NULL)
+
++MAINTAINERCLEANFILES = \
++ $(libdoclet_la_VALASOURCES:.vala=.c) \
+ $(NULL)
+
--- /dev/null
-using Gee;
-
-
+ /* doclet.vala
+ *
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
++
+ using Valadoc;
+ using Valadoc.Api;
+ using Valadoc.Html;
+
+ public class Valadoc.Html.Doclet : Valadoc.Html.BasicDoclet {
+ private const string css_path_package = "style.css";
+ private const string css_path_wiki = "../style.css";
+ private const string css_path = "../style.css";
+
+
+ private const string js_path_package = "scripts.js";
+ private const string js_path_wiki = "../scripts.js";
+ private const string js_path = "../scripts.js";
+
+ private class IndexLinkHelper : LinkHelper {
+ protected override string? from_wiki_to_package (WikiPage from, Api.Package to) {
+ if (from.name != "index.valadoc") {
+ return base.from_wiki_to_package (from, to);;
+ }
+
+ return Path.build_filename (to.name, to.name + ".htm");
+ }
+
+ protected override string? from_wiki_to_wiki (WikiPage from, WikiPage to) {
+ if (from.name != "index.valadoc") {
+ return base.from_wiki_to_wiki (from, to);
+ }
+
+ return Path.build_filename (_settings.pkg_name, translate_wiki_name (to));
+ }
+
+ protected override string? from_wiki_to_node (WikiPage from, Api.Node to) {
+ if (from.name != "index.valadoc") {
+ return base.from_wiki_to_node (from, to);
+ }
+
+ if (enable_browsable_check && (!to.is_browsable(_settings) || !to.package.is_browsable (_settings))) {
+ return null;
+ }
+
+ return Path.build_filename (to.package.name, to.get_full_name () + ".html");
+ }
+ }
+
+ private string get_real_path ( Api.Node element ) {
+ return GLib.Path.build_filename ( this.settings.path, element.package.name, element.get_full_name () + ".html" );
+ }
+
+ public override void process (Settings settings, Api.Tree tree, ErrorReporter reporter) {
+ base.process (settings, tree, reporter);
+
+ DirUtils.create_with_parents (this.settings.path, 0777);
+ copy_directory (icons_dir, settings.path);
+
+ write_wiki_pages (tree, css_path_wiki, js_path_wiki, Path.build_filename(settings.path, settings.pkg_name));
+
+ var tmp = _renderer;
+ _renderer = new HtmlRenderer (settings, new IndexLinkHelper (), this.cssresolver);
+ GLib.FileStream file = GLib.FileStream.open (GLib.Path.build_filename (settings.path, "index.html"), "w");
+ writer = new Html.MarkupWriter (file);
+ _renderer.set_writer (writer);
+ write_file_header (Valadoc.Html.Doclet.css_path_package, Valadoc.Html.Doclet.js_path_package, settings.pkg_name);
+ write_navi_packages (tree);
+ write_package_index_content (tree);
+ write_file_footer ();
+ _renderer = tmp;
+ file = null;
+
+ tree.accept (this);
+ }
+
+ public override void visit_tree (Api.Tree tree) {
+ tree.accept_children (this);
+ }
+
+ public override void visit_package (Package package) {
+ if (!package.is_browsable (settings)) {
+ return ;
+ }
+
+ string pkg_name = package.name;
+ string path = GLib.Path.build_filename ( this.settings.path, pkg_name );
+
+ var rt = DirUtils.create (path, 0777);
+ rt = DirUtils.create (GLib.Path.build_filename (path, "img"), 0777);
+
+ GLib.FileStream file = GLib.FileStream.open (GLib.Path.build_filename (path, "index.htm"), "w");
+ writer = new Html.MarkupWriter (file);
+ _renderer.set_writer (writer);
+ write_file_header (Valadoc.Html.Doclet.css_path, Valadoc.Html.Doclet.js_path, pkg_name);
+ write_navi_package (package);
+ write_package_content (package, package);
+ write_file_footer ();
+ file = null;
+
+ package.accept_all_children (this);
+ }
+
+ public override void visit_namespace (Namespace ns) {
+ string rpath = this.get_real_path (ns);
+
+ if (ns.name != null) {
+ GLib.FileStream file = GLib.FileStream.open (rpath, "w");
+ writer = new Html.MarkupWriter (file);
+ _renderer.set_writer (writer);
+ write_file_header (Valadoc.Html.Doclet.css_path, Valadoc.Html.Doclet.js_path, ns.get_full_name () + " – " + ns.package.name);
+ write_navi_symbol (ns);
+ write_namespace_content (ns, ns);
+ write_file_footer ();
+ file = null;
+ }
+
+ ns.accept_all_children (this);
+ }
+
+ private void process_node (Api.Node node, bool accept_all_children) {
+ string rpath = this.get_real_path (node);
+
+ GLib.FileStream file = GLib.FileStream.open (rpath, "w");
+ writer = new Html.MarkupWriter (file);
+ _renderer.set_writer (writer);
+ write_file_header (css_path, js_path, node.get_full_name() + " – " + node.package.name);
+ if (is_internal_node (node)) {
+ write_navi_symbol (node);
+ } else {
+ write_navi_leaf_symbol (node);
+ }
+ write_symbol_content (node);
+ write_file_footer ();
+ file = null;
+
+ if (accept_all_children) {
+ node.accept_all_children (this);
+ }
+ }
+
+ public override void visit_interface (Interface item) {
+ process_node (item, true);
+ }
+
+ public override void visit_class (Api.Class item) {
+ process_node (item, true);
+ }
+
+ public override void visit_struct (Api.Struct item) {
+ process_node (item, true);
+ }
+
+ public override void visit_error_domain (Api.ErrorDomain item) {
+ process_node (item, true);
+ }
+
+ public override void visit_enum (Api.Enum item) {
+ process_node (item, true);
+ }
+
+ public override void visit_property (Api.Property item) {
+ process_node (item, false);
+ }
+
+ public override void visit_constant (Api.Constant item) {
+ process_node (item, false);
+ }
+
+ public override void visit_field (Api.Field item) {
+ process_node (item, false);
+ }
+
+ public override void visit_error_code (Api.ErrorCode item) {
+ process_node (item, false);
+ }
+
+ public override void visit_enum_value (Api.EnumValue item) {
+ process_node (item, false);
+ }
+
+ public override void visit_delegate (Api.Delegate item) {
+ process_node (item, false);
+ }
+
+ public override void visit_signal (Api.Signal item) {
+ process_node (item, false);
+ }
+
+ public override void visit_method (Api.Method item) {
+ process_node (item, false);
+ }
+ }
+
+
+ public Type register_plugin (Valadoc.ModuleLoader module_loader) {
+ return typeof ( Valadoc.Html.Doclet );
+ }
+
--- /dev/null
-using Valadoc.Api;
-using Gee;
-
+ /* driver.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
++using Valadoc.Api;
+
+ /**
+ * Creates an simpler, minimized, more abstract AST for valacs AST.
+ */
+ public class Valadoc.Drivers.Driver : Object, Valadoc.Driver {
+ private SymbolResolver resolver;
+ private Api.Tree? tree;
+
+ public void write_gir (Settings settings, ErrorReporter reporter) {
+ var gir_writer = new Drivers.GirWriter (resolver);
+
+ // put .gir file in current directory unless -d has been explicitly specified
+ string gir_directory = ".";
+ if (settings.gir_directory != null) {
+ gir_directory = settings.gir_directory;
+ }
+
+ gir_writer.write_file ((Vala.CodeContext) tree.data,
+ gir_directory,
+ "%s-%s.gir".printf (settings.gir_namespace, settings.gir_version),
+ settings.gir_namespace,
+ settings.gir_version,
+ settings.pkg_name);
+ }
+
+ public Api.Tree? build (Settings settings, ErrorReporter reporter) {
+ TreeBuilder builder = new TreeBuilder ();
+ tree = builder.build (settings, reporter);
+ if (reporter.errors > 0) {
+ return null;
+ }
+
+ resolver = new SymbolResolver (builder);
+ tree.accept (resolver);
+
+ return tree;
+ }
+ }
+
+
+ public Type register_plugin (Valadoc.ModuleLoader module_loader) {
+ return typeof (Valadoc.Drivers.Driver);
+ }
+
--- /dev/null
-
+ /* girwriter.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Api;
+
- Gee.List<Content.Taglet> taglets = documentation.find_taglets (cb, typeof(Taglets.Return));
+ /**
+ * Code visitor generating .gir file for the public interface.
+ */
+ public class Valadoc.Drivers.GirWriter : Vala.GIRWriter {
+ private GtkdocRenderer renderer;
+ private SymbolResolver resolver;
+
+ public GirWriter (SymbolResolver resolver) {
+ this.renderer = new GtkdocRenderer ();
+ this.resolver = resolver;
+ }
+
+ private string? translate (Content.Comment? documentation) {
+ if (documentation == null) {
+ return null;
+ }
+
+ renderer.render_symbol (documentation);
+
+ return MarkupWriter.escape (renderer.content);
+ }
+
+ private string? translate_taglet (Content.Taglet? taglet) {
+ if (taglet == null) {
+ return null;
+ }
+
+ renderer.render_children (taglet);
+
+ return MarkupWriter.escape (renderer.content);
+ }
+
+ protected override string? get_interface_comment (Vala.Interface viface) {
+ Interface iface = resolver.resolve (viface) as Interface;
+ return translate (iface.documentation);
+ }
+
+ protected override string? get_struct_comment (Vala.Struct vst) {
+ Struct st = resolver.resolve (vst) as Struct;
+ return translate (st.documentation);
+ }
+
+ protected override string? get_enum_comment (Vala.Enum ven) {
+ Enum en = resolver.resolve (ven) as Enum;
+ return translate (en.documentation);
+ }
+
+ protected override string? get_class_comment (Vala.Class vc) {
+ Class c = resolver.resolve (vc) as Class;
+ return translate (c.documentation);
+ }
+
+ protected override string? get_error_code_comment (Vala.ErrorCode vecode) {
+ ErrorCode ecode = resolver.resolve (vecode) as ErrorCode;
+ return translate (ecode.documentation);
+ }
+
+ protected override string? get_enum_value_comment (Vala.EnumValue vev) {
+ Api.EnumValue ev = resolver.resolve (vev) as Api.EnumValue;
+ return translate (ev.documentation);
+ }
+
+ protected override string? get_constant_comment (Vala.Constant vc) {
+ Constant c = resolver.resolve (vc) as Constant;
+ return translate (c.documentation);
+ }
+
+ protected override string? get_error_domain_comment (Vala.ErrorDomain vedomain) {
+ ErrorDomain edomain = resolver.resolve (vedomain) as ErrorDomain;
+ return translate (edomain.documentation);
+ }
+
+ protected override string? get_field_comment (Vala.Field vf) {
+ Field f = resolver.resolve (vf) as Field;
+ return translate (f.documentation);
+ }
+
+ protected override string? get_delegate_comment (Vala.Delegate vcb) {
+ Delegate cb = resolver.resolve (vcb) as Delegate;
+ return translate (cb.documentation);
+ }
+
+ protected override string? get_method_comment (Vala.Method vm) {
+ Method m = resolver.resolve (vm) as Method;
+ return translate (m.documentation);
+ }
+
+ protected override string? get_property_comment (Vala.Property vprop) {
+ Property prop = resolver.resolve (vprop) as Property;
+ return translate (prop.documentation);
+ }
+
+ protected override string? get_delegate_return_comment (Vala.Delegate vcb) {
+ Delegate cb = resolver.resolve (vcb) as Delegate;
+ if (cb.documentation == null) {
+ return null;
+ }
+
+ Content.Comment? documentation = cb.documentation;
+ if (documentation == null) {
+ return null;
+ }
+
- Gee.List<Content.Taglet> taglets = documentation.find_taglets (sig, typeof(Taglets.Return));
++ Vala.List<Content.Taglet> taglets = documentation.find_taglets (cb, typeof(Taglets.Return));
+ foreach (Content.Taglet taglet in taglets) {
+ return translate_taglet (taglet);
+ }
+
+ return null;
+ }
+
+ protected override string? get_signal_return_comment (Vala.Signal vsig) {
+ Api.Signal sig = resolver.resolve (vsig) as Api.Signal;
+ if (sig.documentation == null) {
+ return null;
+ }
+
+ Content.Comment? documentation = sig.documentation;
+ if (documentation == null) {
+ return null;
+ }
+
- Gee.List<Content.Taglet> taglets = documentation.find_taglets (m, typeof(Taglets.Return));
++ Vala.List<Content.Taglet> taglets = documentation.find_taglets (sig, typeof(Taglets.Return));
+ foreach (Content.Taglet taglet in taglets) {
+ return translate_taglet (taglet);
+ }
+
+ return null;
+ }
+
+ protected override string? get_method_return_comment (Vala.Method vm) {
+ Method m = resolver.resolve (vm) as Method;
+ if (m.documentation == null) {
+ return null;
+ }
+
+ Content.Comment? documentation = m.documentation;
+ if (documentation == null) {
+ return null;
+ }
+
- Gee.List<Content.Taglet> taglets = documentation.find_taglets (symbol, typeof(Taglets.Param));
++ Vala.List<Content.Taglet> taglets = documentation.find_taglets (m, typeof(Taglets.Return));
+ foreach (Content.Taglet taglet in taglets) {
+ return translate_taglet (taglet);
+ }
+
+ return null;
+ }
+
+ protected override string? get_signal_comment (Vala.Signal vsig) {
+ Api.Signal sig = resolver.resolve (vsig) as Api.Signal;
+ return translate (sig.documentation);
+ }
+
+ protected override string? get_parameter_comment (Vala.Parameter param) {
+ Api.Symbol symbol = resolver.resolve (((Vala.Symbol) param.parent_symbol));
+ if (symbol == null) {
+ return null;
+ }
+
+ Content.Comment? documentation = symbol.documentation;
+ if (documentation == null) {
+ return null;
+ }
+
++ Vala.List<Content.Taglet> taglets = documentation.find_taglets (symbol, typeof(Taglets.Param));
+ foreach (Content.Taglet _taglet in taglets) {
+ Taglets.Param taglet = (Taglets.Param) _taglet;
+ if (taglet.parameter_name == param.name) {
+ return translate_taglet (taglet);
+ }
+ }
+
+ return null;
+ }
+ }
+
+
--- /dev/null
-using Gee;
-
+ /* initializerbuilder.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Content;
- private HashMap<Vala.Symbol, Symbol> symbol_map;
+
+ private class Valadoc.Api.InitializerBuilder : Vala.CodeVisitor {
- public InitializerBuilder (SignatureBuilder signature, HashMap<Vala.Symbol, Symbol> symbol_map) {
++ private Vala.HashMap<Vala.Symbol, Symbol> symbol_map;
+ private SignatureBuilder signature;
+
+ private Symbol? resolve (Vala.Symbol symbol) {
+ return symbol_map.get (symbol);
+ }
+
+ private void write_node (Vala.Symbol vsymbol) {
+ signature.append_symbol (resolve (vsymbol));
+ }
+
+ private void write_type (Vala.DataType vsymbol) {
+ if (vsymbol.data_type != null) {
+ write_node (vsymbol.data_type);
+ } else {
+ signature.append_literal ("null");
+ }
+
+ var type_args = vsymbol.get_type_arguments ();
+ if (type_args.size > 0) {
+ signature.append ("<");
+ bool first = true;
+ foreach (Vala.DataType type_arg in type_args) {
+ if (!first) {
+ signature.append (",");
+ } else {
+ first = false;
+ }
+ if (!type_arg.value_owned) {
+ signature.append_keyword ("weak");
+ }
+ signature.append (type_arg.to_qualified_string (null));
+ }
+ signature.append (">");
+ }
+
+ if (vsymbol.nullable) {
+ signature.append ("?");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_array_creation_expression (Vala.ArrayCreationExpression expr) {
+ signature.append_keyword ("new");
+ write_type (expr.element_type);
+ signature.append ("[", false);
+
+ bool first = true;
+ foreach (Vala.Expression size in expr.get_sizes ()) {
+ if (!first) {
+ signature.append (", ", false);
+ }
+ size.accept (this);
+ first = false;
+ }
+
+ signature.append ("]", false);
+
+ if (expr.initializer_list != null) {
+ signature.append (" ", false);
+ expr.initializer_list.accept (this);
+ }
+ }
+
++ public InitializerBuilder (SignatureBuilder signature, Vala.HashMap<Vala.Symbol, Symbol> symbol_map) {
+ this.symbol_map = symbol_map;
+ this.signature = signature;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_binary_expression (Vala.BinaryExpression expr) {
+ expr.left.accept (this);
+
+ switch (expr.operator) {
+ case Vala.BinaryOperator.PLUS:
+ signature.append ("+ ");
+ break;
+
+ case Vala.BinaryOperator.MINUS:
+ signature.append ("- ");
+ break;
+
+ case Vala.BinaryOperator.MUL:
+ signature.append ("* ");
+ break;
+
+ case Vala.BinaryOperator.DIV:
+ signature.append ("/ ");
+ break;
+
+ case Vala.BinaryOperator.MOD:
+ signature.append ("% ");
+ break;
+
+ case Vala.BinaryOperator.SHIFT_LEFT:
+ signature.append ("<< ");
+ break;
+
+ case Vala.BinaryOperator.SHIFT_RIGHT:
+ signature.append (">> ");
+ break;
+
+ case Vala.BinaryOperator.LESS_THAN:
+ signature.append ("< ");
+ break;
+
+ case Vala.BinaryOperator.GREATER_THAN:
+ signature.append ("> ");
+ break;
+
+ case Vala.BinaryOperator.LESS_THAN_OR_EQUAL:
+ signature.append ("<= ");
+ break;
+
+ case Vala.BinaryOperator.GREATER_THAN_OR_EQUAL:
+ signature.append (">= ");
+ break;
+
+ case Vala.BinaryOperator.EQUALITY:
+ signature.append ("== ");
+ break;
+
+ case Vala.BinaryOperator.INEQUALITY:
+ signature.append ("!= ");
+ break;
+
+ case Vala.BinaryOperator.BITWISE_AND:
+ signature.append ("& ");
+ break;
+
+ case Vala.BinaryOperator.BITWISE_OR:
+ signature.append ("| ");
+ break;
+
+ case Vala.BinaryOperator.BITWISE_XOR:
+ signature.append ("^ ");
+ break;
+
+ case Vala.BinaryOperator.AND:
+ signature.append ("&& ");
+ break;
+
+ case Vala.BinaryOperator.OR:
+ signature.append ("|| ");
+ break;
+
+ case Vala.BinaryOperator.IN:
+ signature.append_keyword ("in");
+ signature.append (" ");
+ break;
+
+ case Vala.BinaryOperator.COALESCE:
+ signature.append ("?? ");
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+
+ expr.right.accept (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_unary_expression (Vala.UnaryExpression expr) {
+ switch (expr.operator) {
+ case Vala.UnaryOperator.PLUS:
+ signature.append ("+");
+ break;
+
+ case Vala.UnaryOperator.MINUS:
+ signature.append ("-");
+ break;
+
+ case Vala.UnaryOperator.LOGICAL_NEGATION:
+ signature.append ("!");
+ break;
+
+ case Vala.UnaryOperator.BITWISE_COMPLEMENT:
+ signature.append ("~");
+ break;
+
+ case Vala.UnaryOperator.INCREMENT:
+ signature.append ("++");
+ break;
+
+ case Vala.UnaryOperator.DECREMENT:
+ signature.append ("--");
+ break;
+
+ case Vala.UnaryOperator.REF:
+ signature.append_keyword ("ref");
+ break;
+
+ case Vala.UnaryOperator.OUT:
+ signature.append_keyword ("out");
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ expr.inner.accept (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_assignment (Vala.Assignment a) {
+ a.left.accept (this);
+
+ switch (a.operator) {
+ case Vala.AssignmentOperator.SIMPLE:
+ signature.append ("=");
+ break;
+
+ case Vala.AssignmentOperator.BITWISE_OR:
+ signature.append ("|");
+ break;
+
+ case Vala.AssignmentOperator.BITWISE_AND:
+ signature.append ("&");
+ break;
+
+ case Vala.AssignmentOperator.BITWISE_XOR:
+ signature.append ("^");
+ break;
+
+ case Vala.AssignmentOperator.ADD:
+ signature.append ("+");
+ break;
+
+ case Vala.AssignmentOperator.SUB:
+ signature.append ("-");
+ break;
+
+ case Vala.AssignmentOperator.MUL:
+ signature.append ("*");
+ break;
+
+ case Vala.AssignmentOperator.DIV:
+ signature.append ("/");
+ break;
+
+ case Vala.AssignmentOperator.PERCENT:
+ signature.append ("%");
+ break;
+
+ case Vala.AssignmentOperator.SHIFT_LEFT:
+ signature.append ("<<");
+ break;
+
+ case Vala.AssignmentOperator.SHIFT_RIGHT:
+ signature.append (">>");
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+
+ a.right.accept (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_cast_expression (Vala.CastExpression expr) {
+ if (expr.is_non_null_cast) {
+ signature.append ("(!)");
+ expr.inner.accept (this);
+ return;
+ }
+
+ if (!expr.is_silent_cast) {
+ signature.append ("(", false);
+ write_type (expr.type_reference);
+ signature.append (")", false);
+ }
+
+ expr.inner.accept (this);
+
+ if (expr.is_silent_cast) {
+ signature.append_keyword ("as");
+ write_type (expr.type_reference);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_initializer_list (Vala.InitializerList list) {
+ signature.append ("{", false);
+
+ bool first = true;
+ foreach (Vala.Expression initializer in list.get_initializers ()) {
+ if (!first) {
+ signature.append (", ", false);
+ }
+ first = false;
+ initializer.accept (this);
+ }
+
+ signature.append ("}", false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_member_access (Vala.MemberAccess expr) {
+ if (expr.symbol_reference != null) {
+ expr.symbol_reference.accept (this);
+ } else {
+ signature.append (expr.member_name);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_element_access (Vala.ElementAccess expr) {
+ expr.container.accept (this);
+ signature.append ("[", false);
+
+ bool first = true;
+ foreach (Vala.Expression index in expr.get_indices ()) {
+ if (!first) {
+ signature.append (", ", false);
+ }
+ first = false;
+
+ index.accept (this);
+ }
+
+ signature.append ("]", false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_pointer_indirection (Vala.PointerIndirection expr) {
+ signature.append ("*", false);
+ expr.inner.accept (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_addressof_expression (Vala.AddressofExpression expr) {
+ signature.append ("&", false);
+ expr.inner.accept (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_reference_transfer_expression (Vala.ReferenceTransferExpression expr) {
+ signature.append ("(", false).append_keyword ("owned", false).append (")", false);
+ expr.inner.accept (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_type_check (Vala.TypeCheck expr) {
+ expr.expression.accept (this);
+ signature.append_keyword ("is");
+ write_type (expr.type_reference);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_method_call (Vala.MethodCall expr) {
+ // symbol-name:
+ expr.call.symbol_reference.accept (this);
+
+ // parameters:
+ signature.append (" (", false);
+ bool first = true;
+ foreach (Vala.Expression literal in expr.get_argument_list ()) {
+ if (!first) {
+ signature.append (", ", false);
+ }
+
+ literal.accept (this);
+ first = false;
+ }
+ signature.append (")", false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_slice_expression (Vala.SliceExpression expr) {
+ expr.container.accept (this);
+ signature.append ("[", false);
+ expr.start.accept (this);
+ signature.append (":", false);
+ expr.stop.accept (this);
+ signature.append ("]", false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_base_access (Vala.BaseAccess expr) {
+ signature.append_keyword ("base", false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_postfix_expression (Vala.PostfixExpression expr) {
+ expr.inner.accept (this);
+ if (expr.increment) {
+ signature.append ("++", false);
+ } else {
+ signature.append ("--", false);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_object_creation_expression (Vala.ObjectCreationExpression expr) {
+ if (!expr.struct_creation) {
+ signature.append_keyword ("new");
+ }
+
+ signature.append_symbol (resolve (expr.symbol_reference));
+
+ signature.append (" (", false);
+
+ //TODO: rm conditional space
+ bool first = true;
+ foreach (Vala.Expression arg in expr.get_argument_list ()) {
+ if (!first) {
+ signature.append (", ", false);
+ }
+ arg.accept (this);
+ first = false;
+ }
+
+ signature.append (")", false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_sizeof_expression (Vala.SizeofExpression expr) {
+ signature.append_keyword ("sizeof", false).append (" (", false);
+ write_type (expr.type_reference);
+ signature.append (")", false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_typeof_expression (Vala.TypeofExpression expr) {
+ signature.append_keyword ("typeof", false).append (" (", false);
+ write_type (expr.type_reference);
+ signature.append (")", false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_lambda_expression (Vala.LambdaExpression expr) {
+ signature.append ("(", false);
+
+ bool first = true;
+ foreach (Vala.Parameter param in expr.get_parameters ()) {
+ if (!first) {
+ signature.append (", ", false);
+ }
+ signature.append (param.name, false);
+ first = false;
+ }
+
+
+ signature.append (") => {", false);
+ signature.append_highlighted (" [...] ", false);
+ signature.append ("}", false);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_boolean_literal (Vala.BooleanLiteral lit) {
+ signature.append_literal (lit.to_string (), false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_character_literal (Vala.CharacterLiteral lit) {
+ signature.append_literal (lit.to_string (), false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_integer_literal (Vala.IntegerLiteral lit) {
+ signature.append_literal (lit.to_string (), false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_real_literal (Vala.RealLiteral lit) {
+ signature.append_literal (lit.to_string (), false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_regex_literal (Vala.RegexLiteral lit) {
+ signature.append_literal (lit.to_string (), false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_string_literal (Vala.StringLiteral lit) {
+ signature.append_literal (lit.to_string (), false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_null_literal (Vala.NullLiteral lit) {
+ signature.append_literal (lit.to_string (), false);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_field (Vala.Field field) {
+ write_node (field);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_constant (Vala.Constant constant) {
+ write_node (constant);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_enum_value (Vala.EnumValue ev) {
+ write_node (ev);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_error_code (Vala.ErrorCode ec) {
+ write_node (ec);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_delegate (Vala.Delegate d) {
+ write_node (d);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_method (Vala.Method m) {
+ write_node (m);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_creation_method (Vala.CreationMethod m) {
+ write_node (m);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_signal (Vala.Signal sig) {
+ write_node (sig);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_class (Vala.Class c) {
+ write_node (c);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_struct (Vala.Struct s) {
+ write_node (s);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_interface (Vala.Interface i) {
+ write_node (i);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_enum (Vala.Enum en) {
+ write_node (en);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_error_domain (Vala.ErrorDomain ed) {
+ write_node (ed);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_property (Vala.Property prop) {
+ write_node (prop);
+ }
+ }
+
--- /dev/null
-using Valadoc.Api;
-using Gee;
+ /* symbolresolver.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
- private HashMap<Vala.Symbol, Symbol> symbol_map;
+
++using Valadoc.Api;
+
+ public class Valadoc.Drivers.SymbolResolver : Visitor {
- Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
++ private Vala.HashMap<Vala.Symbol, Symbol> symbol_map;
+ private Valadoc.Api.Class glib_error;
+ private Api.Tree root;
+
+ public SymbolResolver (TreeBuilder builder) {
+ this.symbol_map = builder.get_symbol_map ();
+ this.glib_error = builder.get_glib_error ();
+ }
+
+ public Symbol? resolve (Vala.Symbol symbol) {
+ return symbol_map.get (symbol);
+ }
+
+ private void resolve_thrown_list (Symbol symbol, Vala.List<Vala.DataType> types) {
+ foreach (Vala.DataType type in types) {
+ Vala.ErrorDomain vala_edom = (Vala.ErrorDomain) type.data_type;
+ Symbol? edom = symbol_map.get (vala_edom);
+ symbol.add_child (edom ?? glib_error);
+ }
+ }
+
+ private void resolve_array_type_references (Api.Array ptr) {
+ Api.Item data_type = ptr.data_type;
+ if (data_type == null) {
+ // void
+ } else if (data_type is Api.Array) {
+ resolve_array_type_references ((Api.Array) data_type);
+ } else if (data_type is Pointer) {
+ resolve_pointer_type_references ((Api.Pointer) data_type);
+ } else {
+ resolve_type_reference ((TypeReference) data_type);
+ }
+ }
+
+ private void resolve_pointer_type_references (Pointer ptr) {
+ Api.Item type = ptr.data_type;
+ if (type == null) {
+ // void
+ } else if (type is Api.Array) {
+ resolve_array_type_references ((Api.Array) type);
+ } else if (type is Pointer) {
+ resolve_pointer_type_references ((Pointer) type);
+ } else {
+ resolve_type_reference ((TypeReference) type);
+ }
+ }
+
+ private void resolve_type_reference (TypeReference reference) {
+ Vala.DataType vtyperef = (Vala.DataType) reference.data;
+ if (vtyperef is Vala.ErrorType) {
+ Vala.ErrorDomain verrdom = ((Vala.ErrorType) vtyperef).error_domain;
+ if (verrdom != null) {
+ reference.data_type = resolve (verrdom);
+ } else {
+ reference.data_type = glib_error;
+ }
+ } else if (vtyperef is Vala.DelegateType) {
+ reference.data_type = resolve (((Vala.DelegateType) vtyperef).delegate_symbol);
+ } else if (vtyperef is Vala.GenericType) {
+ reference.data_type = resolve (((Vala.GenericType) vtyperef).type_parameter);
+ } else if (vtyperef.data_type != null) {
+ reference.data_type = resolve (vtyperef.data_type);
+ }
+
+ // Type parameters:
+ foreach (TypeReference type_param_ref in reference.get_type_arguments ()) {
+ resolve_type_reference (type_param_ref);
+ }
+
+ if (reference.data_type is Pointer) {
+ resolve_pointer_type_references ((Pointer)reference.data_type);
+ } else if (reference.data_type is Api.Array) {
+ resolve_array_type_references ((Api.Array)reference.data_type);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_tree (Api.Tree item) {
+ this.root = item;
+ item.accept_children (this);
+ this.root = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_package (Package item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_namespace (Namespace item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_interface (Interface item) {
- Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
++ Vala.Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+ foreach (var type_ref in interfaces) {
+ resolve_type_reference (type_ref);
+ }
+
+ if (item.base_type != null) {
+ resolve_type_reference (item.base_type);
+ }
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_class (Class item) {
++ Vala.Collection<TypeReference> interfaces = item.get_implemented_interface_list ();
+ foreach (TypeReference type_ref in interfaces) {
+ resolve_type_reference (type_ref);
+ }
+
+ if (item.base_type != null) {
+ resolve_type_reference (item.base_type);
+ }
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_struct (Struct item) {
+ if (item.base_type != null) {
+ resolve_type_reference (item.base_type);
+ }
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_property (Property item) {
+ Vala.Property vala_property = item.data as Vala.Property;
+ Vala.Property? base_vala_property = null;
+
+ if (vala_property.base_property != null) {
+ base_vala_property = vala_property.base_property;
+ } else if (vala_property.base_interface_property != null) {
+ base_vala_property = vala_property.base_interface_property;
+ }
+ if (base_vala_property == vala_property && vala_property.base_interface_property != null) {
+ base_vala_property = vala_property.base_interface_property;
+ }
+ if (base_vala_property != null) {
+ item.base_property = (Property?) resolve (base_vala_property);
+ }
+
+ resolve_type_reference (item.property_type);
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_field (Field item) {
+ resolve_type_reference (item.field_type);
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_constant (Constant item) {
+ resolve_type_reference (item.constant_type);
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_delegate (Delegate item) {
+ Vala.Delegate vala_delegate = item.data as Vala.Delegate;
+
+ resolve_type_reference (item.return_type);
+
+ resolve_thrown_list (item, vala_delegate.get_error_types ());
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_signal (Api.Signal item) {
+ resolve_type_reference (item.return_type);
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_method (Method item) {
+ Vala.Method vala_method = item.data as Vala.Method;
+ Vala.Method? base_vala_method = null;
+ if (vala_method.base_method != null) {
+ base_vala_method = vala_method.base_method;
+ } else if (vala_method.base_interface_method != null) {
+ base_vala_method = vala_method.base_interface_method;
+ }
+ if (base_vala_method == vala_method && vala_method.base_interface_method != null) {
+ base_vala_method = vala_method.base_interface_method;
+ }
+ if (base_vala_method != null) {
+ item.base_method = (Method?) resolve (base_vala_method);
+ }
+
+ resolve_thrown_list (item, vala_method.get_error_types ());
+
+ resolve_type_reference (item.return_type);
+
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_type_parameter (TypeParameter item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_formal_parameter (FormalParameter item) {
+ if (item.ellipsis) {
+ return;
+ }
+
+ if (((Vala.Parameter) item.data).initializer != null) {
+ SignatureBuilder signature = new SignatureBuilder ();
+ InitializerBuilder ibuilder = new InitializerBuilder (signature, symbol_map);
+ ((Vala.Parameter) item.data).initializer.accept (ibuilder);
+ item.default_value = signature.get ();
+ }
+
+ resolve_type_reference (item.parameter_type);
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_error_domain (ErrorDomain item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_error_code (ErrorCode item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_enum (Enum item) {
+ item.accept_all_children (this, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_enum_value (Api.EnumValue item) {
+
+ if (((Vala.EnumValue) item.data).value != null) {
+ SignatureBuilder signature = new SignatureBuilder ();
+ InitializerBuilder ibuilder = new InitializerBuilder (signature, symbol_map);
+ ((Vala.EnumValue) item.data).value.accept (ibuilder);
+ item.default_value = signature.get ();
+ }
+
+ item.accept_all_children (this, false);
+ }
+ }
+
+
+
--- /dev/null
-AM_CPPFLAGS = \
- $(GLIB_CFLAGS) \
- $(NULL)
-AM_LDFLAGS = \
- $(GLIB_LIBS) \
- $(NULL)
-
-BUILT_SOURCES = \
- $(NULL)
-noinst_PROGRAMS = \
- $(NULL)
-
-TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) TOPBUILDDIR=$(abs_top_builddir) TOPSRCDIR=$(abs_top_srcdir) $(srcdir)/testrunner.sh
+ NULL =
+
-if HAVE_LIBVALA_0_20_X
-TESTS += drivers/driver-0-20.vala
-endif
-
-if HAVE_LIBVALA_0_22_X
-TESTS += drivers/driver-0-22.vala
-endif
-
-if HAVE_LIBVALA_0_24_X
-TESTS += drivers/driver-0-24.vala
-endif
-
-if HAVE_LIBVALA_0_26_X
-TESTS += drivers/driver-0-26.vala
-endif
-
-if HAVE_LIBVALA_0_28_X
-TESTS += drivers/driver-0-28.vala
-endif
++TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) PACKAGE_SUFFIX=$(PACKAGE_SUFFIX) TOPBUILDDIR=$(abs_top_builddir) TOPSRCDIR=$(abs_top_srcdir) $(srcdir)/testrunner.sh
+
+ TESTS = \
+ libvaladoc/errorreporter.vala \
+ libvaladoc/markupreader.vala \
+ libvaladoc/gtkdoc-scanner.vala \
+ libvaladoc/parser/manyrule.vala \
+ libvaladoc/parser/oneofrule.vala \
+ libvaladoc/parser/sequencerule.vala \
+ libvaladoc/parser/optionalrule.vala \
+ libvaladoc/parser/stubrule.vala \
+ $(NULL)
+
-if HAVE_LIBVALA_0_30_X
-TESTS += drivers/driver-0-30.vala
-endif
++check-TESTS: $(TESTS)
++ @EXEEXT=$(EXEEXT) PACKAGE_SUFFIX=$(PACKAGE_SUFFIX) TOPBUILDDIR=$(abs_top_builddir) TOPSRCDIR=$(abs_top_srcdir) $(srcdir)/testrunner.sh $(TESTS)
++ G_DEBUG=fatal_warnings $(builddir)/driver
++
++AM_CFLAGS = \
++ -DPACKAGE_DATADIR=\"$(libdir)/valadoc\" \
++ -DPACKAGE_VERSION=\"$(VERSION)\" \
++ -DTOP_SRC_DIR=\"$(abs_top_srcdir)\" \
++ -I$(top_srcdir)/libvaladoc/ \
++ -I$(top_srcdir)/gee \
++ -I$(top_srcdir)/ccode \
++ -I$(top_srcdir)/vala \
++ -I$(top_srcdir)/codegen \
++ $(GLIB_CFLAGS) \
++ $(GMODULE_CFLAGS) \
++ $(LIBGVC_CFLAGS) \
++ $(NULL)
+
-if HAVE_LIBVALA_0_32_X
-TESTS += drivers/driver-0-32.vala
-endif
++BUILT_SOURCES = driver.vala.stamp
+
-if HAVE_LIBVALA_0_34_X
-TESTS += drivers/driver-0-34.vala
-endif
++check_PROGRAMS = driver
+
-if HAVE_LIBVALA_0_36_X
-TESTS += drivers/driver-0-36.vala
-endif
++driver_VALASOURCES = \
++ drivers/driver-test.vala \
++ drivers/generic-api-test.vala \
++ $(top_srcdir)/valadoc/driver.vala \
++ $(top_srcdir)/valadoc/girwriter.vala \
++ $(top_srcdir)/valadoc/initializerbuilder.vala \
++ $(top_srcdir)/valadoc/symbolresolver.vala \
++ $(top_srcdir)/valadoc/treebuilder.vala \
++ $(NULL)
++
++driver_SOURCES = \
++ driver.vala.stamp \
++ drivers/driver-test.c \
++ drivers/generic-api-test.c \
++ driver.c \
++ girwriter.c \
++ initializerbuilder.c \
++ symbolresolver.c \
++ treebuilder.c \
++ $(NULL)
+
-check-TESTS: $(TESTS)
- @EXEEXT=$(EXEEXT) TOPBUILDDIR=$(abs_top_builddir) TOPSRCDIR=$(abs_top_srcdir) $(srcdir)/testrunner.sh $(TESTS)
++driver_LDADD = \
++ $(top_builddir)/libvaladoc/libvaladoc@PACKAGE_SUFFIX@.la \
++ $(top_builddir)/vala/libvala@PACKAGE_SUFFIX@.la \
++ $(top_builddir)/ccode/libvalaccode.la \
++ $(top_builddir)/codegen/libvalaccodegen.la \
++ $(GLIB_LIBS) \
++ $(GMODULE_LIBS) \
++ $(LIBGVC_LIBS) \
++ $(NULL)
+
++driver.vala.stamp: $(driver_VALASOURCES) $(top_srcdir)/vala/libvala@PACKAGE_SUFFIX@.vapi $(top_srcdir)/libvaladoc/valadoc@PACKAGE_SUFFIX@.vapi
++ $(VALA_V)$(VALAC) \
++ $(VALAFLAGS) \
++ -C \
++ --vapidir $(top_srcdir)/vapi \
++ --pkg gmodule-2.0 \
++ --pkg gobject-2.0 \
++ --pkg libgvc \
++ --vapidir $(top_srcdir)/vala --pkg libvala@PACKAGE_SUFFIX@ \
++ --vapidir $(top_srcdir)/ccode --pkg ccode \
++ --vapidir $(top_srcdir)/codegen --pkg codegen \
++ --vapidir $(top_srcdir)/libvaladoc --pkg valadoc@PACKAGE_SUFFIX@ \
++ --pkg config \
++ $(filter %.vala %.c,$^)
++ touch $@
+
+ EXTRA_DIST = \
++ driver.vala.stamp \
++ $(driver_SOURCES) \
+ testrunner.sh \
+ drivers/api-test.data.vapi \
++ drivers/driver-test.vala \
+ drivers/generic-api-test.vala \
+ libvaladoc/parser/generic-scanner.vala \
+ $(TESTS) \
+ $(NULL)
+
++MAINTAINERCLEANFILES = \
++ driver.vala.stamp \
++ $(driver_SOURCES) \
++ $(NULL)
--- /dev/null
--- /dev/null
++public static void main () {
++ test_driver ();
++}
--- /dev/null
-using Valadoc;
-using Gee;
+ /* api-test.vala
+ *
+ * Copyright (C) 2013 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
-[CCode (name = "TOP_SRC_DIR")]
+
++using Valadoc;
+
- Gee.List<Api.Node> enumvalues = en.get_children_by_type (Api.NodeType.ENUM_VALUE, false);
++[CCode (cname = "TOP_SRC_DIR")]
+ extern const string TOP_SRC_DIR;
+
+
+ public static void test_enum_global (Api.Enum? en, Api.Package pkg, Api.Namespace global_ns) {
+ assert (en != null);
+
+ // (.Enum check)
+ assert (en.get_cname () == "TestEnumGlobal");
+ // (.TypeSymbol check)
+ assert (en.is_basic_type == false);
+ // (.Symbol check)
+ assert (en.is_deprecated == false);
+ assert (en.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (en.get_full_name () == "TestEnumGlobal");
+ assert (en.get_filename () == "api-test.data.vapi");
+ assert (en.name == "TestEnumGlobal");
+ assert (en.nspace == global_ns);
+ assert (en.package == pkg);
+
+
- Gee.List<Api.Node> methods = en.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> enumvalues = en.get_children_by_type (Api.NodeType.ENUM_VALUE, false);
+ assert (enumvalues.size == 2);
+
+
+ bool enval1 = false;
+ bool enval2 = false;
+
+ foreach (Api.Node node in enumvalues) {
+ Api.EnumValue enval = node as Api.EnumValue;
+ assert (enval != null);
+
+ switch (enval.name) {
+ case "ENVAL1":
+ // (.EnumValue)
+ assert (enval.default_value != null);
+ assert (enval.has_default_value == true);
+ assert (enval.get_cname () == "TEST_ENUM_GLOBAL_ENVAL1");
+ // (.Symbol check)
+ assert (enval.is_deprecated == false);
+ assert (enval.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (enval.get_full_name () == "TestEnumGlobal.ENVAL1");
+ assert (enval.get_filename () == "api-test.data.vapi");
+ assert (enval.nspace == global_ns);
+ assert (enval.package == pkg);
+
+ enval1 = true;
+ break;
+
+ case "ENVAL2":
+ // (.EnumValue)
+ assert (enval.default_value == null);
+ assert (enval.has_default_value == false);
+ assert (enval.get_cname () == "TEST_ENUM_GLOBAL_ENVAL2");
+ // (.Symbol check)
+ assert (enval.is_deprecated == false);
+ assert (enval.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (enval.get_full_name () == "TestEnumGlobal.ENVAL2");
+ assert (enval.get_filename () == "api-test.data.vapi");
+ assert (enval.nspace == global_ns);
+ assert (enval.package == pkg);
+
+ enval2 = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (enval1 == true);
+ assert (enval2 == true);
+
+
+
- Gee.List<Api.Node> nodes = en.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> methods = en.get_children_by_type (Api.NodeType.METHOD, false);
+ assert (methods.size == 1);
+
+ Api.Method method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_enum_global_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestEnumGlobal.method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+
+ methods = en.get_children_by_type (Api.NodeType.STATIC_METHOD, false);
+ assert (methods.size == 1);
+
+ method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_enum_global_static_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == true);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestEnumGlobal.static_method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "static_method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.CLASS,
+ Api.NodeType.CONSTANT,
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.ENUM,
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FIELD,
+ Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.STRUCT,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> errcodes = err.get_children_by_type (Api.NodeType.ERROR_CODE, false);
++ Vala.List<Api.Node> nodes = en.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+ }
+
+
+ public static void test_erroromain_global (Api.ErrorDomain? err, Api.Package pkg, Api.Namespace global_ns) {
+ assert (err != null);
+
+ // (.ErrorDomain check)
+ assert (err.get_cname () == "TestErrDomGlobal");
+ //assert (err.get_dbus_name () == "");
+ // (.TypeSymbol check)
+ assert (err.is_basic_type == false);
+ // (.Symbol check)
+ assert (err.is_deprecated == false);
+ assert (err.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (err.get_full_name () == "TestErrDomGlobal");
+ assert (err.get_filename () == "api-test.data.vapi");
+ assert (err.name == "TestErrDomGlobal");
+ assert (err.nspace == global_ns);
+ assert (err.package == pkg);
+
+
- Gee.List<Api.Node> methods = err.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> errcodes = err.get_children_by_type (Api.NodeType.ERROR_CODE, false);
+ assert (errcodes.size == 2);
+
+
+ bool errc1 = false;
+ bool errc2 = false;
+
+ foreach (Api.Node node in errcodes) {
+ Api.ErrorCode errc = node as Api.ErrorCode;
+ assert (errc != null);
+
+ switch (errc.name) {
+ case "ERROR1":
+ // (.EnumValue)
+ assert (errc.get_cname () == "TEST_ERR_DOM_GLOBAL_ERROR1");
+ // (.Symbol check)
+ assert (errc.is_deprecated == false);
+ assert (errc.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (errc.get_full_name () == "TestErrDomGlobal.ERROR1");
+ assert (errc.get_filename () == "api-test.data.vapi");
+ assert (errc.nspace == global_ns);
+ assert (errc.package == pkg);
+
+ errc1 = true;
+ break;
+
+ case "ERROR2":
+ // (.EnumValue)
+ assert (errc.get_cname () == "TEST_ERR_DOM_GLOBAL_ERROR2");
+ // (.Symbol check)
+ assert (errc.is_deprecated == false);
+ assert (errc.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (errc.get_full_name () == "TestErrDomGlobal.ERROR2");
+ assert (errc.get_filename () == "api-test.data.vapi");
+ assert (errc.nspace == global_ns);
+ assert (errc.package == pkg);
+
+ errc2 = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (errc1 == true);
+ assert (errc2 == true);
+
+
+
- Gee.List<Api.Node> nodes = err.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> methods = err.get_children_by_type (Api.NodeType.METHOD, false);
+ assert (methods.size == 1);
+
+ Api.Method method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_err_dom_global_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestErrDomGlobal.method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+
+ methods = err.get_children_by_type (Api.NodeType.STATIC_METHOD, false);
+ assert (methods.size == 1);
+
+ method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_err_dom_global_static_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == true);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestErrDomGlobal.static_method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "static_method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.CLASS,
+ Api.NodeType.CONSTANT,
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.ENUM,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FIELD,
+ Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.STRUCT,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> methods = cl.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> nodes = err.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+ }
+
+
+ public static void test_class_global (Api.Class? cl, Api.Package pkg, Api.Namespace global_ns) {
+ assert (cl != null);
+
+ // (.Class check)
+ assert (cl.base_type == null);
+ assert (cl.get_cname () == "TestClassGlobal");
+ assert (cl.get_type_id () == "TYPE_TEST_CLASS_GLOBAL");
+ assert (cl.get_ref_function_cname () == "test_class_global_ref");
+ assert (cl.get_unref_function_cname () == "test_class_global_unref");
+ assert (cl.get_param_spec_function_cname () == "param_spec_test_class_global");
+ assert (cl.get_set_value_function_cname () == "value_set_test_class_global");
+ assert (cl.get_get_value_function_cname () == "value_get_test_class_global");
+ assert (cl.get_take_value_function_cname () == "value_take_test_class_global");
+ assert (cl.get_dbus_name () == null);
+ assert (cl.get_implemented_interface_list ().size == 0);
+ assert (cl.get_full_implemented_interface_list ().size == 0);
+ assert (cl.is_abstract == false);
+ assert (cl.is_fundamental == true);
+ // (.Symbol check)
+ assert (cl.is_deprecated == false);
+ assert (cl.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestClassGlobal.property3");
+ assert (cl.get_full_name () == "TestClassGlobal");
+ assert (cl.get_filename () == "api-test.data.vapi");
+ assert (cl.name == "TestClassGlobal");
+ assert (cl.nspace == global_ns);
+ assert (cl.package == pkg);
+
+
- Gee.List<Api.Node> properties = cl.get_children_by_type (Api.NodeType.PROPERTY, false);
++ Vala.List<Api.Node> methods = cl.get_children_by_type (Api.NodeType.METHOD, false);
+ assert (methods.size == 1);
+
+ Api.Method method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_class_global_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestClassGlobal.method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+
+ methods = cl.get_children_by_type (Api.NodeType.STATIC_METHOD, false);
+ assert (methods.size == 1);
+
+ method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_class_global_static_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == true);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestClassGlobal.static_method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "static_method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+
+ methods = cl.get_children_by_type (Api.NodeType.CREATION_METHOD, false);
+ bool default_constr = false;
+ bool named_constr = false;
+
+ foreach (Api.Node node in methods) {
+ method = node as Api.Method;
+ assert (method != null);
+
+ switch (method.name) {
+ case "TestClassGlobal":
+ // (.Method check)
+ assert (method.get_cname () == "test_class_global_new");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == true);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestClassGlobal.TestClassGlobal");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+ default_constr = true;
+ break;
+
+ case "TestClassGlobal.named":
+ // (.Method check)
+ assert (method.get_cname () == "test_class_global_new_named");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == true);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestClassGlobal.TestClassGlobal.named");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+ named_constr = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (default_constr == true);
+ assert (named_constr == true);
+
+
+
- Gee.List<Api.Node> delegates = cl.get_children_by_type (Api.NodeType.DELEGATE, false);
++ Vala.List<Api.Node> properties = cl.get_children_by_type (Api.NodeType.PROPERTY, false);
+ bool prop1 = false;
+ bool prop2 = false;
+ bool prop3 = false;
+
+ foreach (Api.Node node in properties) {
+ Api.Property property = node as Api.Property;
+ assert (property != null);
+
+ switch (property.name) {
+ case "property1":
+ assert (property.get_cname () == "property1");
+ assert (property.property_type != null);
+ assert (property.is_virtual == false);
+ assert (property.is_abstract == false);
+ assert (property.is_override == false);
+ assert (property.is_dbus_visible == true);
+ assert (property.setter != null);
+ assert (property.getter != null);
+ assert (property.base_property == null);
+ // (.Symbol check)
+ assert (property.is_deprecated == false);
+ assert (property.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (property.get_full_name () == "TestClassGlobal.property1");
+ assert (property.get_filename () == "api-test.data.vapi");
+ assert (property.nspace == global_ns);
+ assert (property.package == pkg);
+
+
+ assert (property.getter.get_cname () == "test_class_global_get_property1");
+ assert (property.getter.is_construct == false);
+ assert (property.getter.is_set == false);
+ assert (property.getter.is_get == true);
+ assert (property.getter.is_owned == false);
+ // (.Symbol check)
+ assert (property.getter.is_deprecated == false);
+ assert (property.getter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestClassGlobal.property2");
+ assert (property.getter.get_filename () == "api-test.data.vapi");
+ assert (property.getter.nspace == global_ns);
+ assert (property.getter.package == pkg);
+
+
+ assert (property.setter.get_cname () == "test_class_global_set_property1");
+ assert (property.setter.is_construct == false);
+ assert (property.setter.is_get == false);
+ assert (property.setter.is_set == true);
+ assert (property.setter.is_owned == false);
+ // (.Symbol check)
+ assert (property.setter.is_deprecated == false);
+ assert (property.setter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestClassGlobal.property2");
+ assert (property.setter.get_filename () == "api-test.data.vapi");
+ assert (property.setter.nspace == global_ns);
+ assert (property.setter.package == pkg);
+
+ prop1 = true;
+ break;
+
+ case "property2":
+ assert (property.get_cname () == "property2");
+ assert (property.property_type != null);
+ assert (property.is_virtual == false);
+ assert (property.is_abstract == false);
+ assert (property.is_override == false);
+ assert (property.is_dbus_visible == true);
+ assert (property.setter == null);
+ assert (property.getter != null);
+ assert (property.base_property == null);
+ // (.Symbol check)
+ assert (property.is_deprecated == false);
+ assert (property.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (property.get_full_name () == "TestClassGlobal.property2");
+ assert (property.get_filename () == "api-test.data.vapi");
+ assert (property.nspace == global_ns);
+ assert (property.package == pkg);
+
+ assert (property.getter.get_cname () == "test_class_global_get_property2");
+ assert (property.getter.is_construct == false);
+ assert (property.getter.is_set == false);
+ assert (property.getter.is_get == true);
+ assert (property.getter.is_owned == false);
+ // (.Symbol check)
+ assert (property.getter.is_deprecated == false);
+ assert (property.getter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestClassGlobal.property2");
+ assert (property.getter.get_filename () == "api-test.data.vapi");
+ assert (property.getter.nspace == global_ns);
+ assert (property.getter.package == pkg);
+
+ prop2 = true;
+ break;
+
+
+ case "property3":
+ assert (property.get_cname () == "property3");
+ assert (property.property_type != null);
+ assert (property.is_virtual == false);
+ assert (property.is_abstract == false);
+ assert (property.is_override == false);
+ assert (property.is_dbus_visible == true);
+ assert (property.setter != null);
+ assert (property.getter != null);
+ assert (property.base_property == null);
+ // (.Symbol check)
+ assert (property.is_deprecated == false);
+ assert (property.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (property.get_full_name () == "TestClassGlobal.property3");
+ assert (property.get_filename () == "api-test.data.vapi");
+ assert (property.nspace == global_ns);
+ assert (property.package == pkg);
+
+ assert (property.getter.get_cname () == "test_class_global_get_property3");
+ assert (property.getter.is_construct == false);
+ assert (property.getter.is_set == false);
+ assert (property.getter.is_get == true);
+ assert (property.getter.is_owned == true);
+ // (.Symbol check)
+ assert (property.getter.is_deprecated == false);
+ assert (property.getter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestClassGlobal.property3");
+ assert (property.getter.get_filename () == "api-test.data.vapi");
+ assert (property.getter.nspace == global_ns);
+ assert (property.getter.package == pkg);
+
+
+ assert (property.setter.get_cname () == "test_class_global_set_property3");
+ assert (property.setter.is_construct == true);
+ assert (property.setter.is_get == false);
+ assert (property.setter.is_set == true);
+ assert (property.setter.is_owned == false);
+ // (.Symbol check)
+ assert (property.setter.is_deprecated == false);
+ assert (property.setter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestClassGlobal.property3");
+ assert (property.setter.get_filename () == "api-test.data.vapi");
+ assert (property.setter.nspace == global_ns);
+ assert (property.setter.package == pkg);
+
+
+ prop3 = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+ assert (prop1);
+ assert (prop2);
+ assert (prop3);
+
+
- Gee.List<Api.Node> signals = cl.get_children_by_type (Api.NodeType.SIGNAL, false);
++ Vala.List<Api.Node> delegates = cl.get_children_by_type (Api.NodeType.DELEGATE, false);
+ assert (delegates.size == 1);
+
+ Api.Delegate del = delegates.get (0) as Api.Delegate;
+ assert (del != null);
+
+ // (.Delegate check)
+ assert (del.get_cname () == "TestClassGlobalFoo");
+ assert (del.return_type != null);
+ assert (del.is_static == false);
+ // (.Symbol check)
+ assert (del.is_deprecated == false);
+ assert (del.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestClassGlobal.property3");
+ assert (del.get_filename () == "api-test.data.vapi");
+ assert (del.nspace == global_ns);
+ assert (del.package == pkg);
+
+
+
- Gee.List<Api.Node> constants = cl.get_children_by_type (Api.NodeType.CONSTANT, false);
++ Vala.List<Api.Node> signals = cl.get_children_by_type (Api.NodeType.SIGNAL, false);
+ assert (signals.size == 1);
+
+ Api.Signal sig = signals.get (0) as Api.Signal;
+ assert (sig != null);
+
+ // (.Signal check)
+ assert (sig.get_cname () == "sig");
+ assert (sig.is_virtual == false);
+ assert (sig.return_type != null);
+ //assert (sig.is_static == false);
+ // (.Symbol check)
+ assert (sig.is_deprecated == false);
+ assert (sig.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (sig.get_full_name () == "TestClassGlobal.property3");
+ assert (sig.get_filename () == "api-test.data.vapi");
+ assert (sig.nspace == global_ns);
+ assert (sig.package == pkg);
+
+
+
- Gee.List<Api.Node> fields = cl.get_children_by_type (Api.NodeType.FIELD, false);
++ Vala.List<Api.Node> constants = cl.get_children_by_type (Api.NodeType.CONSTANT, false);
+ assert (constants.size == 1);
+
+ Api.Constant constant = constants.get (0) as Api.Constant;
+ assert (constant != null);
+ // (.Constant check)
+ assert (constant.get_cname () == "TEST_CLASS_GLOBAL_constant");
+ // (.Symbol check)
+ assert (constant.is_deprecated == false);
+ assert (constant.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (constant.get_full_name () == "TestClassGlobal.constant");
+ assert (constant.get_filename () == "api-test.data.vapi");
+ assert (constant.name == "constant");
+ assert (constant.nspace == global_ns);
+ assert (constant.package == pkg);
+
+
- Gee.List<Api.Node> classes = cl.get_children_by_type (Api.NodeType.CLASS, false);
++ Vala.List<Api.Node> fields = cl.get_children_by_type (Api.NodeType.FIELD, false);
+
+ bool field1 = false;
+ bool field2 = false;
+ foreach (Api.Node node in fields) {
+ Api.Field field = node as Api.Field;
+ assert (field != null);
+
+ switch (field.name) {
+ case "field1":
+ // (.Field check)
+ assert (field.get_cname () == "test_class_global_field1");
+ assert (field.is_static == true);
+ assert (field.is_volatile == false);
+ // (.Symbol check)
+ assert (field.is_deprecated == false);
+ assert (field.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (field.get_full_name () == "TestClassGlobal.field1");
+ assert (field.get_filename () == "api-test.data.vapi");
+ assert (field.nspace == global_ns);
+ assert (field.package == pkg);
+
+ field1 = true;
+ break;
+
+ case "field2":
+ // (.Field check)
+ assert (field.get_cname () == "field2");
+ assert (field.is_static == false);
+ assert (field.is_volatile == false);
+ // (.Symbol check)
+ assert (field.is_deprecated == false);
+ assert (field.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (field.get_full_name () == "TestClassGlobal.field2");
+ assert (field.get_filename () == "api-test.data.vapi");
+ assert (field.nspace == global_ns);
+ assert (field.package == pkg);
+
+ field2 = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (field1 == true);
+ assert (field2 == true);
+
+
+
- Gee.List<Api.Node> structs = cl.get_children_by_type (Api.NodeType.STRUCT, false);
++ Vala.List<Api.Node> classes = cl.get_children_by_type (Api.NodeType.CLASS, false);
+ assert (classes.size == 1);
+
+ Api.Class? subcl = classes.get (0) as Api.Class;
+ assert (subcl != null);
+ assert (subcl.base_type == null);
+ // (.Symbol check)
+ assert (subcl.is_deprecated == false);
+ assert (subcl.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (subcl.get_full_name () == "TestClassGlobal.InnerClass");
+ assert (subcl.get_filename () == "api-test.data.vapi");
+ assert (subcl.nspace == global_ns);
+ assert (subcl.package == pkg);
+
+
+
- Gee.List<Api.Node> nodes = cl.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> structs = cl.get_children_by_type (Api.NodeType.STRUCT, false);
+ assert (structs.size == 1);
+
+ Api.Struct? substru = structs.get (0) as Api.Struct;
+ assert (substru != null);
+ // (.Struct check)
+ assert (substru.base_type == null);
+ assert (substru.get_cname () == "TestClassGlobalInnerStruct");
+ assert (substru.get_free_function_cname () == null);
+ assert (substru.get_dup_function_cname () == null);
+ assert (substru.get_type_id () == null);
+ // (.Symbol check)
+ assert (substru.is_deprecated == false);
+ assert (substru.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (substru.get_full_name () == "TestClassGlobal.InnerStruct");
+ assert (substru.get_filename () == "api-test.data.vapi");
+ assert (substru.name == "InnerStruct");
+ assert (substru.nspace == global_ns);
+ assert (substru.package == pkg);
+
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.ENUM,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> methods = iface.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> nodes = cl.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+ }
+
+
+ public static void test_interface_global (Api.Interface? iface, Api.Package pkg, Api.Namespace global_ns) {
+ assert (iface != null);
+
+ // (.Interface check)
+ assert (iface.base_type == null);
+ assert (iface.get_implemented_interface_list ().size == 0);
+ assert (iface.get_full_implemented_interface_list ().size == 0);
+ assert (iface.get_cname () == "TestInterfaceGlobal");
+ assert (iface.get_dbus_name () == null);
+ // (.Symbol check)
+ assert (iface.is_deprecated == false);
+ assert (iface.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (iface.get_full_name () == "TestInterfaceGlobal");
+ assert (iface.get_filename () == "api-test.data.vapi");
+ assert (iface.name == "TestInterfaceGlobal");
+ assert (iface.nspace == global_ns);
+ assert (iface.package == pkg);
+
+
- Gee.List<Api.Node> properties = iface.get_children_by_type (Api.NodeType.PROPERTY, false);
++ Vala.List<Api.Node> methods = iface.get_children_by_type (Api.NodeType.METHOD, false);
+ assert (methods.size == 1);
+
+ Api.Method method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_interface_global_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestInterfaceGlobal.method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+
+ methods = iface.get_children_by_type (Api.NodeType.STATIC_METHOD, false);
+ assert (methods.size == 1);
+
+ method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_interface_global_static_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == true);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestInterfaceGlobal.static_method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "static_method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
- Gee.List<Api.Node> delegates = iface.get_children_by_type (Api.NodeType.DELEGATE, false);
++ Vala.List<Api.Node> properties = iface.get_children_by_type (Api.NodeType.PROPERTY, false);
+ bool prop1 = false;
+ bool prop2 = false;
+ bool prop3 = false;
+
+ foreach (Api.Node node in properties) {
+ Api.Property property = node as Api.Property;
+ assert (property != null);
+
+ switch (property.name) {
+ case "property1":
+ assert (property.get_cname () == "property1");
+ assert (property.property_type != null);
+ assert (property.is_virtual == false);
+ assert (property.is_abstract == false);
+ assert (property.is_override == false);
+ assert (property.is_dbus_visible == true);
+ assert (property.setter != null);
+ assert (property.getter != null);
+ assert (property.base_property == null);
+ // (.Symbol check)
+ assert (property.is_deprecated == false);
+ assert (property.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (property.get_full_name () == "TestInterfaceGlobal.property1");
+ assert (property.get_filename () == "api-test.data.vapi");
+ assert (property.nspace == global_ns);
+ assert (property.package == pkg);
+
+
+ assert (property.getter.get_cname () == "test_interface_global_get_property1");
+ assert (property.getter.is_construct == false);
+ assert (property.getter.is_set == false);
+ assert (property.getter.is_get == true);
+ assert (property.getter.is_owned == false);
+ // (.Symbol check)
+ assert (property.getter.is_deprecated == false);
+ assert (property.getter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestInterfaceGlobal.property2");
+ assert (property.getter.get_filename () == "api-test.data.vapi");
+ assert (property.getter.nspace == global_ns);
+ assert (property.getter.package == pkg);
+
+
+ assert (property.setter.get_cname () == "test_interface_global_set_property1");
+ assert (property.setter.is_construct == false);
+ assert (property.setter.is_get == false);
+ assert (property.setter.is_set == true);
+ assert (property.setter.is_owned == false);
+ // (.Symbol check)
+ assert (property.setter.is_deprecated == false);
+ assert (property.setter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestInterfaceGlobal.property2");
+ assert (property.setter.get_filename () == "api-test.data.vapi");
+ assert (property.setter.nspace == global_ns);
+ assert (property.setter.package == pkg);
+
+ prop1 = true;
+ break;
+
+ case "property2":
+ assert (property.get_cname () == "property2");
+ assert (property.property_type != null);
+ assert (property.is_virtual == false);
+ assert (property.is_abstract == false);
+ assert (property.is_override == false);
+ assert (property.is_dbus_visible == true);
+ assert (property.setter == null);
+ assert (property.getter != null);
+ assert (property.base_property == null);
+ // (.Symbol check)
+ assert (property.is_deprecated == false);
+ assert (property.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (property.get_full_name () == "TestInterfaceGlobal.property2");
+ assert (property.get_filename () == "api-test.data.vapi");
+ assert (property.nspace == global_ns);
+ assert (property.package == pkg);
+
+ assert (property.getter.get_cname () == "test_interface_global_get_property2");
+ assert (property.getter.is_construct == false);
+ assert (property.getter.is_set == false);
+ assert (property.getter.is_get == true);
+ assert (property.getter.is_owned == false);
+ // (.Symbol check)
+ assert (property.getter.is_deprecated == false);
+ assert (property.getter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestInterfaceGlobal.property2");
+ assert (property.getter.get_filename () == "api-test.data.vapi");
+ assert (property.getter.nspace == global_ns);
+ assert (property.getter.package == pkg);
+
+ prop2 = true;
+ break;
+
+
+ case "property3":
+ assert (property.get_cname () == "property3");
+ assert (property.property_type != null);
+ assert (property.is_virtual == false);
+ assert (property.is_abstract == false);
+ assert (property.is_override == false);
+ assert (property.is_dbus_visible == true);
+ assert (property.setter != null);
+ assert (property.getter != null);
+ assert (property.base_property == null);
+ // (.Symbol check)
+ assert (property.is_deprecated == false);
+ assert (property.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (property.get_full_name () == "TestInterfaceGlobal.property3");
+ assert (property.get_filename () == "api-test.data.vapi");
+ assert (property.nspace == global_ns);
+ assert (property.package == pkg);
+
+ assert (property.getter.get_cname () == "test_interface_global_get_property3");
+ assert (property.getter.is_construct == false);
+ assert (property.getter.is_set == false);
+ assert (property.getter.is_get == true);
+ assert (property.getter.is_owned == true);
+ // (.Symbol check)
+ assert (property.getter.is_deprecated == false);
+ assert (property.getter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestInterfaceGlobal.property3");
+ assert (property.getter.get_filename () == "api-test.data.vapi");
+ assert (property.getter.nspace == global_ns);
+ assert (property.getter.package == pkg);
+
+
+ assert (property.setter.get_cname () == "test_interface_global_set_property3");
+ assert (property.setter.is_construct == true);
+ assert (property.setter.is_get == false);
+ assert (property.setter.is_set == true);
+ assert (property.setter.is_owned == false);
+ // (.Symbol check)
+ assert (property.setter.is_deprecated == false);
+ assert (property.setter.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestInterfaceGlobal.property3");
+ assert (property.setter.get_filename () == "api-test.data.vapi");
+ assert (property.setter.nspace == global_ns);
+ assert (property.setter.package == pkg);
+
+
+ prop3 = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+ assert (prop1);
+ assert (prop2);
+ assert (prop3);
+
+
+
- Gee.List<Api.Node> signals = iface.get_children_by_type (Api.NodeType.SIGNAL, false);
++ Vala.List<Api.Node> delegates = iface.get_children_by_type (Api.NodeType.DELEGATE, false);
+ assert (delegates.size == 1);
+
+ Api.Delegate del = delegates.get (0) as Api.Delegate;
+ assert (del != null);
+
+ // (.Delegate check)
+ assert (del.get_cname () == "TestInterfaceGlobalFoo");
+ assert (del.return_type != null);
+ assert (del.is_static == false);
+ // (.Symbol check)
+ assert (del.is_deprecated == false);
+ assert (del.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (del.get_full_name () == "TestClassGlobal.property3");
+ assert (del.get_filename () == "api-test.data.vapi");
+ assert (del.nspace == global_ns);
+ assert (del.package == pkg);
+
+
+
- Gee.List<Api.Node> constants = iface.get_children_by_type (Api.NodeType.CONSTANT, false);
++ Vala.List<Api.Node> signals = iface.get_children_by_type (Api.NodeType.SIGNAL, false);
+ assert (signals.size == 1);
+
+ Api.Signal sig = signals.get (0) as Api.Signal;
+ assert (sig != null);
+
+ // (.Signal check)
+ assert (sig.get_cname () == "sig");
+ assert (sig.is_virtual == false);
+ assert (sig.return_type != null);
+ //assert (sig.is_static == false);
+ // (.Symbol check)
+ assert (sig.is_deprecated == false);
+ assert (sig.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (sig.get_full_name () == "TestClassGlobal.property3");
+ assert (sig.get_filename () == "api-test.data.vapi");
+ assert (sig.nspace == global_ns);
+ assert (sig.package == pkg);
+
+
+
- Gee.List<Api.Node> nodes = iface.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> constants = iface.get_children_by_type (Api.NodeType.CONSTANT, false);
+ assert (constants.size == 1);
+
+ Api.Constant constant = constants.get (0) as Api.Constant;
+ assert (constant != null);
+ // (.Constant check)
+ assert (constant.get_cname () == "TEST_INTERFACE_GLOBAL_constant");
+ // (.Symbol check)
+ assert (constant.is_deprecated == false);
+ assert (constant.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (constant.get_full_name () == "TestInterfaceGlobal.constant");
+ assert (constant.get_filename () == "api-test.data.vapi");
+ assert (constant.name == "constant");
+ assert (constant.nspace == global_ns);
+ assert (constant.package == pkg);
+
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.ENUM,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FIELD,
+ Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.STRUCT,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> methods = stru.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> nodes = iface.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+ }
+
+
+ public static void test_struct_global (Api.Struct? stru, Api.Package pkg, Api.Namespace global_ns) {
+ assert (stru != null);
+ // (.Struct check)
+ assert (stru.base_type == null);
+ assert (stru.get_cname () == "TestStructGlobal");
+ assert (stru.get_free_function_cname () == null);
+ assert (stru.get_dup_function_cname () == null);
+ assert (stru.get_type_id () == null);
+ // (.Symbol check)
+ assert (stru.is_deprecated == false);
+ assert (stru.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ //assert (property.getter.get_full_name () == "TestClassGlobal.property3");
+ assert (stru.get_full_name () == "TestStructGlobal");
+ assert (stru.get_filename () == "api-test.data.vapi");
+ assert (stru.name == "TestStructGlobal");
+ assert (stru.nspace == global_ns);
+ assert (stru.package == pkg);
+
+
- Gee.List<Api.Node> constants = stru.get_children_by_type (Api.NodeType.CONSTANT, false);
++ Vala.List<Api.Node> methods = stru.get_children_by_type (Api.NodeType.METHOD, false);
+ assert (methods.size == 1);
+
+ Api.Method method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_struct_global_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestStructGlobal.method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+
+ methods = stru.get_children_by_type (Api.NodeType.STATIC_METHOD, false);
+ assert (methods.size == 1);
+
+ method = methods.get (0) as Api.Method;
+ assert (method != null);
+
+ // (.Method check)
+ assert (method.get_cname () == "test_struct_global_static_method");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == true);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestStructGlobal.static_method");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "static_method");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+
+ methods = stru.get_children_by_type (Api.NodeType.CREATION_METHOD, false);
+ bool default_constr = false;
+ bool named_constr = false;
+
+ foreach (Api.Node node in methods) {
+ method = node as Api.Method;
+ assert (method != null);
+
+ switch (method.name) {
+ case "TestStructGlobal":
+ // (.Method check)
+ assert (method.get_cname () == "test_struct_global_init");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == true);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestStructGlobal.TestStructGlobal");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+ default_constr = true;
+ break;
+
+ case "TestStructGlobal.named":
+ // (.Method check)
+ assert (method.get_cname () == "test_struct_global_init_named");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == true);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "TestStructGlobal.TestStructGlobal.named");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+ named_constr = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (default_constr == true);
+ assert (named_constr == true);
+
+
+
- Gee.List<Api.Node> fields = stru.get_children_by_type (Api.NodeType.FIELD, false);
++ Vala.List<Api.Node> constants = stru.get_children_by_type (Api.NodeType.CONSTANT, false);
+ assert (constants.size == 1);
+
+ Api.Constant constant = constants.get (0) as Api.Constant;
+ assert (constant != null);
+ // (.Constant check)
+ assert (constant.get_cname () == "TEST_STRUCT_GLOBAL_constant");
+ // (.Symbol check)
+ assert (constant.is_deprecated == false);
+ assert (constant.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (constant.get_full_name () == "TestStructGlobal.constant");
+ assert (constant.get_filename () == "api-test.data.vapi");
+ assert (constant.name == "constant");
+ assert (constant.nspace == global_ns);
+ assert (constant.package == pkg);
+
+
+
- Gee.List<Api.Node> nodes = stru.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> fields = stru.get_children_by_type (Api.NodeType.FIELD, false);
+
+ bool field1 = false;
+ bool field2 = false;
+ foreach (Api.Node node in fields) {
+ Api.Field field = node as Api.Field;
+ assert (field != null);
+
+ switch (field.name) {
+ case "field1":
+ // (.Field check)
+ assert (field.get_cname () == "test_struct_global_field1");
+ assert (field.is_static == true);
+ assert (field.is_volatile == false);
+ // (.Symbol check)
+ assert (field.is_deprecated == false);
+ assert (field.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (field.get_full_name () == "TestStructGlobal.field1");
+ assert (field.get_filename () == "api-test.data.vapi");
+ assert (field.nspace == global_ns);
+ assert (field.package == pkg);
+
+ field1 = true;
+ break;
+
+ case "field2":
+ // (.Field check)
+ assert (field.get_cname () == "field2");
+ assert (field.is_static == false);
+ assert (field.is_volatile == false);
+ // (.Symbol check)
+ assert (field.is_deprecated == false);
+ assert (field.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (field.get_full_name () == "TestStructGlobal.field2");
+ assert (field.get_filename () == "api-test.data.vapi");
+ assert (field.nspace == global_ns);
+ assert (field.package == pkg);
+
+ field2 = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (field1 == true);
+ assert (field2 == true);
+
+
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.CLASS,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.ENUM,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.STRUCT,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> methods = ns.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> nodes = stru.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+ }
+
+
+ public static void param_test (Api.Namespace ns, Api.Package pkg) {
- Gee.List<Api.Node> nodes = m.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> methods = ns.get_children_by_type (Api.NodeType.METHOD, false);
+
+ bool func1 = false;
+ bool func2 = false;
+ bool func3 = false;
+ bool func4 = false;
+ bool func5 = false;
+ bool func6 = false;
+ bool func7 = false;
+ bool func8 = false;
+ bool func9 = false;
+ bool func10 = false;
+ bool func11 = false;
+ bool func12 = false;
+ bool func13 = false;
+ bool func14 = false;
+
+ foreach (Api.Node node in methods) {
+ Api.Method m = node as Api.Method;
+ assert (m != null);
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.CLASS,
+ Api.NodeType.CONSTANT,
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.ENUM,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FIELD,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.METHOD,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.STATIC_METHOD,
+ Api.NodeType.STRUCT,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> params = m.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false);
++ Vala.List<Api.Node> nodes = m.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+
- Gee.List<Api.Node> nodes = ns.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> params = m.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false);
+
+ switch (m.name) {
+ case "test_function_param_1":
+ assert (params.size == 0);
+
+ func1 = true;
+ break;
+
+ case "test_function_param_2":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_2.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func2 = true;
+ break;
+
+ case "test_function_param_3":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == true);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_3.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func3 = true;
+ break;
+
+ case "test_function_param_4":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == true);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_4.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func4 = true;
+ break;
+
+ case "test_function_param_5":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_5.o");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "o");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Class);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "GLib.Object");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == true);
+ assert (param.parameter_type.is_owned == true);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func5 = true;
+ break;
+
+ case "test_function_param_6":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_6.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == true);
+
+ func6 = true;
+ break;
+
+ case "test_function_param_7":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == true);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == null);
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == null);
+ // param type:
+ assert (param.parameter_type.data_type == null);
+
+ func7 = true;
+ break;
+
+ case "test_function_param_8":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value != null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == true);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_8.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func8 = true;
+ break;
+
+ case "test_function_param_9":
+ assert (params.size == 7);
+
+ Api.FormalParameter? param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_9.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+
+
+ param = params.get (1) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == true);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_9.b");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "b");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+
+
+ param = params.get (2) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == true);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_9.c");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "c");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+
+
+ param = params.get (3) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_9.d");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "d");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Class);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "GLib.Object");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == true);
+ assert (param.parameter_type.is_owned == true);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+
+
+ param = params.get (4) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_9.e");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "e");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == true);
+
+
+
+ param = params.get (5) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value != null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == true);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_9.f");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "f");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Struct);
+ assert (((Api.Symbol) param.parameter_type.data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+
+
+ param = params.get (6) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == true);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == null);
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == null);
+ // param type:
+ assert (param.parameter_type.data_type == null);
+
+ func9 = true;
+ break;
+
+ case "test_function_param_10":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_10.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Pointer);
+ assert (((Api.Pointer) param.parameter_type.data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Pointer) param.parameter_type.data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Pointer) param.parameter_type.data_type).data_type).data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func10 = true;
+ break;
+
+ case "test_function_param_11":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_11.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Pointer);
+ assert (((Api.Pointer) param.parameter_type.data_type).data_type is Api.Pointer);
+ assert (((Api.Pointer) ((Api.Pointer) param.parameter_type.data_type).data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Pointer) ((Api.Pointer) param.parameter_type.data_type).data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Pointer) ((Api.Pointer) param.parameter_type.data_type).data_type).data_type).data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func11 = true;
+ break;
+
+ case "test_function_param_12":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_12.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Array);
+ //assert (((Api.Array) param.parameter_type.data_type).dimension == 1);
+ assert (((Api.Array) param.parameter_type.data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Array) param.parameter_type.data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Array) param.parameter_type.data_type).data_type).data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func12 = true;
+ break;
+
+ case "test_function_param_13":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_13.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Array);
+ //assert (((Api.Array) param.parameter_type.data_type).dimension == 2);
+ assert (((Api.Array) param.parameter_type.data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Array) param.parameter_type.data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Array) param.parameter_type.data_type).data_type).data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func13 = true;
+ break;
+
+ case "test_function_param_14":
+ assert (params.size == 1);
+
+ Api.FormalParameter param = params.get (0) as Api.FormalParameter;
+ assert (param != null);
+ // (.FormalParameter)
+ assert (param.default_value == null);
+ assert (param.is_out == false);
+ assert (param.is_ref == false);
+ assert (param.has_default_value == false);
+ assert (param.parameter_type != null);
+ assert (param.ellipsis == false);
+ // (.Symbol check)
+ assert (param.is_deprecated == false);
+ assert (param.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (param.get_full_name () == "ParamTest.test_function_param_14.a");
+ assert (param.get_filename () == "api-test.data.vapi");
+ assert (param.nspace == ns);
+ assert (param.package == pkg);
+ assert (param.name == "a");
+ // param type:
+ assert (param.parameter_type.data_type != null);
+ assert (param.parameter_type.data_type is Api.Array);
+ //assert (((Api.Array) param.parameter_type.data_type).dimension == 1);
+ assert (((Api.Array) param.parameter_type.data_type).data_type is Api.TypeReference);
+ //assert (((Api.Array) ((Api.Array) param.parameter_type.data_type).data_type).dimension == 1);
+ assert (((Api.TypeReference) ((Api.Array) param.parameter_type.data_type).data_type).data_type is Api.Array);
+ assert (((Api.Array) ((Api.TypeReference) ((Api.Array) param.parameter_type.data_type).data_type).data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Array) ((Api.TypeReference) ((Api.Array) param.parameter_type.data_type).data_type).data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Array) ((Api.TypeReference) ((Api.Array) param.parameter_type.data_type).data_type).data_type).data_type).data_type).get_full_name () == "int");
+ assert (param.parameter_type.get_type_arguments ().size == 0);
+ assert (param.parameter_type.pass_ownership == false);
+ assert (param.parameter_type.is_owned == false);
+ assert (param.parameter_type.is_unowned == false);
+ assert (param.parameter_type.is_weak == false);
+ assert (param.parameter_type.is_dynamic == false);
+ assert (param.parameter_type.is_nullable == false);
+
+ func14 = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (func1 == true);
+ assert (func2 == true);
+ assert (func3 == true);
+ assert (func4 == true);
+ assert (func5 == true);
+ assert (func6 == true);
+ assert (func7 == true);
+ assert (func8 == true);
+ assert (func9 == true);
+ assert (func10 == true);
+ assert (func11 == true);
+ assert (func12 == true);
+ assert (func13 == true);
+ assert (func14 == true);
+
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.CLASS,
+ Api.NodeType.CONSTANT,
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.ENUM,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FIELD,
+ Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.STATIC_METHOD,
+ Api.NodeType.STRUCT,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> methods = ns.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> nodes = ns.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+ }
+
+
+ public static void return_test (Api.Namespace ns, Api.Package pkg) {
- Gee.List<Api.Node> nodes = m.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> methods = ns.get_children_by_type (Api.NodeType.METHOD, false);
+
+ bool func1 = false;
+ bool func2 = false;
+ bool func3 = false;
+ bool func4 = false;
+ bool func5 = false;
+ bool func6 = false;
+ bool func7 = false;
+ bool func8 = false;
+ bool func9 = false;
+
+ foreach (Api.Node node in methods) {
+ Api.Method m = node as Api.Method;
+ assert (m != null);
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.CLASS,
+ Api.NodeType.CONSTANT,
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.ENUM,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FIELD,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.METHOD,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.STATIC_METHOD,
+ Api.NodeType.STRUCT,
+ Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> methods = ns.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> nodes = m.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+
+ Api.TypeReference? ret = m.return_type;
+ assert (ret != null);
+
+ switch (m.name) {
+ case "test_function_1":
+ assert (ret.data_type == null);
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == false);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == false);
+
+ func1 = true;
+ break;
+
+ case "test_function_2":
+ assert (ret.data_type is Api.Struct);
+ assert (((Api.Struct) ret.data_type).get_full_name () == "int");
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == false);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == false);
+
+ func2 = true;
+ break;
+
+ case "test_function_3":
+ assert (ret.data_type is Api.Struct);
+ assert (((Api.Struct) ret.data_type).get_full_name () == "int");
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == false);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == true);
+
+ func3 = true;
+ break;
+
+ case "test_function_4":
+ assert (ret.data_type is Api.Class);
+ assert (((Api.Class) ret.data_type).get_full_name () == "string");
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == true);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == false);
+
+ func4 = true;
+ break;
+
+ case "test_function_5":
+ assert (ret.data_type is Api.Pointer);
+ assert (((Api.Pointer) ret.data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Pointer) ret.data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Pointer) ret.data_type).data_type).data_type).get_full_name () == "int");
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == false);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == false);
+
+ func5 = true;
+ break;
+
+ case "test_function_6":
+ assert (ret.data_type is Api.Pointer);
+ assert (((Api.Pointer) ret.data_type).data_type is Api.Pointer);
+ assert (((Api.Pointer) ((Api.Pointer) ret.data_type).data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Pointer) ((Api.Pointer) ret.data_type).data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Pointer) ((Api.Pointer) ret.data_type).data_type).data_type).data_type).get_full_name () == "int");
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == false);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == false);
+
+ func6 = true;
+ break;
+
+ case "test_function_7":
+ assert (ret.data_type is Api.Array);
+ assert (((Api.Array) ret.data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Array) ret.data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Array) ret.data_type).data_type).data_type).get_full_name () == "int");
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == false);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == false);
+
+ func7 = true;
+ break;
+
+ case "test_function_8":
+ assert (ret.data_type is Api.Array);
+ //assert (((Api.Array) ret.data_type).dimension == 1);
+ assert (((Api.Array) ret.data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Array) ret.data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Array) ret.data_type).data_type).data_type).get_full_name () == "int");
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == false);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == false);
+
+ func8 = true;
+ break;
+
+ case "test_function_9":
+ assert (ret.data_type is Api.Array);
+ //assert (((Api.Array) ret.data_type).dimension == 1);
+ assert (((Api.Array) ret.data_type).data_type is Api.TypeReference);
+ //assert (((Api.Array) ((Api.Array) ret.data_type).data_type).dimension == 1);
+ assert (((Api.TypeReference) ((Api.Array) ret.data_type).data_type).data_type is Api.Array);
+ assert (((Api.Array) ((Api.TypeReference) ((Api.Array) ret.data_type).data_type).data_type).data_type is Api.TypeReference);
+ assert (((Api.TypeReference) ((Api.Array) ((Api.TypeReference) ((Api.Array) ret.data_type).data_type).data_type).data_type).data_type is Api.Struct);
+ assert (((Api.Struct) ((Api.TypeReference) ((Api.Array) ((Api.TypeReference) ((Api.Array) ret.data_type).data_type).data_type).data_type).data_type).get_full_name () == "int");
+ assert (ret.get_type_arguments ().size == 0);
+ assert (ret.pass_ownership == false);
+ assert (ret.is_owned == false);
+ assert (ret.is_unowned == false);
+ assert (ret.is_weak == false);
+ assert (ret.is_dynamic == false);
+ assert (ret.is_nullable == false);
+
+ func9 = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (func1 == true);
+ assert (func2 == true);
+ assert (func3 == true);
+ assert (func4 == true);
+ assert (func5 == true);
+ assert (func6 == true);
+ assert (func7 == true);
+ assert (func8 == true);
+ assert (func9 == true);
+ }
+
+
+ public static void version_test (Api.Namespace ns, Api.Package pkg) {
- Gee.List<Api.Node> nodes = m.get_children_by_types (forbidden, false);
++ Vala.List<Api.Node> methods = ns.get_children_by_type (Api.NodeType.METHOD, false);
+
+ bool func1 = false;
+ bool func2 = false;
+ bool func3 = false;
+ #if VALA_0_32
+ bool func4 = false;
+ bool func5 = false;
+ bool func6 = false;
+ bool func7 = false;
+ bool func8 = false;
+ bool func9 = false;
+ #endif
+
+ foreach (Api.Node node in methods) {
+ Api.Method m = node as Api.Method;
+ assert (m != null);
+
+ Api.NodeType[] forbidden = {
+ Api.NodeType.CLASS,
+ Api.NodeType.CONSTANT,
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.ENUM,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ERROR_DOMAIN,
+ Api.NodeType.FIELD,
+ Api.NodeType.INTERFACE,
+ Api.NodeType.METHOD,
+ Api.NodeType.NAMESPACE,
+ Api.NodeType.PACKAGE,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.PROPERTY_ACCESSOR,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.STATIC_METHOD,
+ Api.NodeType.STRUCT,
+ Api.NodeType.FORMAL_PARAMETER,
+ Api.NodeType.TYPE_PARAMETER
+ };
+
- Gee.List<Api.Node> methods = global_ns.get_children_by_type (Api.NodeType.METHOD, false);
++ Vala.List<Api.Node> nodes = m.get_children_by_types (forbidden, false);
+ assert (nodes.size == 0);
+
+ Api.TypeReference? ret = m.return_type;
+ assert (ret != null);
+
+ switch (m.name) {
+ case "test_function_1":
+ assert (m.get_attribute ("Deprecated") != null);
+ assert (m.is_deprecated == true);
+
+ func1 = true;
+ break;
+
+ case "test_function_2":
+ assert (m.get_attribute ("Deprecated").get_argument ("since").get_value_as_string () == "\"1.0\"");
+ assert (m.get_attribute ("Deprecated").get_argument ("replacement").get_value_as_string () == "\"test_function_4\"");
+ assert (m.is_deprecated == true);
+
+ func2 = true;
+ break;
+
+ case "test_function_3":
+ //assert (m.get_attribute ("Experimental") != null);
+
+ func3 = true;
+ break;
+
+ #if VALA_0_32
+ case "test_function_4":
+ assert (m.get_attribute ("Version").get_argument ("since").get_value_as_string () == "\"2.0\"");
+ assert (m.is_deprecated == false);
+
+ func4 = true;
+ break;
+
+ case "test_function_5":
+ assert (m.get_attribute ("Version").get_argument ("deprecated").get_value_as_boolean () == true);
+ assert (m.is_deprecated == true);
+
+ func5 = true;
+ break;
+
+ case "test_function_6":
+ assert (m.get_attribute ("Version").get_argument ("deprecated").get_value_as_boolean () == true);
+ assert (m.get_attribute ("Version").get_argument ("deprecated_since").get_value_as_string () == "\"2.0\"");
+ assert (m.get_attribute ("Version").get_argument ("replacement").get_value_as_string () == "\"test_function_4\"");
+ assert (m.get_attribute ("Version").get_argument ("since").get_value_as_string () == "\"1.0\"");
+ assert (m.is_deprecated == true);
+
+ func6 = true;
+ break;
+
+ case "test_function_7":
+ assert (m.get_attribute ("Version").get_argument ("deprecated_since").get_value_as_string () == "\"2.0\"");
+ assert (m.is_deprecated == true);
+
+ func7 = true;
+ break;
+
+ case "test_function_8":
+ assert (m.get_attribute ("Version").get_argument ("deprecated").get_value_as_boolean () == false);
+ assert (m.is_deprecated == false);
+
+ func8 = true;
+ break;
+
+ case "test_function_9":
+ //assert (m.get_attribute ("Version").get_argument ("experimental").get_value_as_boolean () == true);
+
+ func9 = true;
+ break;
+ #endif
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (func1 == true);
+ assert (func2 == true);
+ assert (func3 == true);
+ #if VALA_0_32
+ assert (func4 == true);
+ assert (func5 == true);
+ assert (func6 == true);
+ assert (func7 == true);
+ assert (func8 == true);
+ assert (func9 == true);
+ #endif
+ }
+
+
+ public static void test_global_ns (Api.Namespace global_ns, Api.Package pkg) {
- Gee.List<Api.Node> delegates = global_ns.get_children_by_type (Api.NodeType.DELEGATE, false);
++ Vala.List<Api.Node> methods = global_ns.get_children_by_type (Api.NodeType.METHOD, false);
+ assert (methods.size == 1);
+
+ Api.Method method = methods.get (0) as Api.Method;
+ assert (method != null);
+ // (.Method check)
+ assert (method.get_cname () == "test_function_global");
+ //assert (method.get_dbus_name () == null);
+ //assert (method.get_dbus_result_name () == null);
+ //assert (method.is_dbus_visible == false);
+ assert (method.base_method == null);
+ assert (method.is_yields == false);
+ assert (method.is_abstract == false);
+ assert (method.is_virtual == false);
+ assert (method.is_override == false);
+ assert (method.is_static == false);
+ assert (method.is_constructor == false);
+ assert (method.is_inline == false);
+ // (.Symbol check)
+ assert (method.is_deprecated == false);
+ assert (method.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (method.get_full_name () == "test_function_global");
+ assert (method.get_filename () == "api-test.data.vapi");
+ assert (method.name == "test_function_global");
+ assert (method.nspace == global_ns);
+ assert (method.package == pkg);
+
+
+
- Gee.List<Api.Node> fields = global_ns.get_children_by_type (Api.NodeType.FIELD, false);
++ Vala.List<Api.Node> delegates = global_ns.get_children_by_type (Api.NodeType.DELEGATE, false);
+ assert (delegates.size == 1);
+
+ Api.Delegate del = delegates.get (0) as Api.Delegate;
+ assert (del != null);
+ // (.Delegate check)
+ assert (del.get_cname () == "test_delegate_global");
+ assert (del.is_static == false);
+ // (.TypeSymbol check)
+ assert (del.is_basic_type == false);
+ // (.Symbol check)
+ assert (del.is_deprecated == false);
+ assert (del.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (del.get_full_name () == "test_delegate_global");
+ assert (del.get_filename () == "api-test.data.vapi");
+ assert (del.name == "test_delegate_global");
+ assert (del.nspace == global_ns);
+ assert (del.package == pkg);
+
+
+
- Gee.List<Api.Node> constants = global_ns.get_children_by_type (Api.NodeType.CONSTANT, false);
++ Vala.List<Api.Node> fields = global_ns.get_children_by_type (Api.NodeType.FIELD, false);
+ assert (fields.size == 1);
+
+ Api.Field field = fields.get (0) as Api.Field;
+ assert (field != null);
+ // (.Field check)
+ assert (field.get_cname () == "test_field_global");
+ assert (field.is_static == false);
+ assert (field.is_volatile == false);
+ // (.Symbol check)
+ assert (field.is_deprecated == false);
+ assert (field.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (field.get_full_name () == "test_field_global");
+ assert (field.get_filename () == "api-test.data.vapi");
+ assert (field.name == "test_field_global");
+ assert (field.nspace == global_ns);
+ assert (field.package == pkg);
+
+
+
- Gee.List<Api.Node> enums = global_ns.get_children_by_type (Api.NodeType.ENUM, false);
++ Vala.List<Api.Node> constants = global_ns.get_children_by_type (Api.NodeType.CONSTANT, false);
+ assert (constants.size == 1);
+
+ Api.Constant constant = constants.get (0) as Api.Constant;
+ assert (constant != null);
+ // (.Constant check)
+ assert (constant.get_cname () == "test_const_global");
+ // (.Symbol check)
+ assert (constant.is_deprecated == false);
+ assert (constant.accessibility == Api.SymbolAccessibility.PUBLIC);
+ // (.Node)
+ assert (constant.get_full_name () == "test_const_global");
+ assert (constant.get_filename () == "api-test.data.vapi");
+ assert (constant.name == "test_const_global");
+ assert (constant.nspace == global_ns);
+ assert (constant.package == pkg);
+
+
+
- Gee.List<Api.Node> errordomains = global_ns.get_children_by_type (Api.NodeType.ERROR_DOMAIN, false);
++ Vala.List<Api.Node> enums = global_ns.get_children_by_type (Api.NodeType.ENUM, false);
+ assert (enums.size == 1);
+
+ Api.Enum en = enums.get (0) as Api.Enum;
+ test_enum_global (en, pkg, global_ns);
+
+
+
- Gee.List<Api.Node> classes = global_ns.get_children_by_type (Api.NodeType.CLASS, false);
++ Vala.List<Api.Node> errordomains = global_ns.get_children_by_type (Api.NodeType.ERROR_DOMAIN, false);
+ assert (errordomains.size == 1);
+
+ Api.ErrorDomain err = errordomains.get (0) as Api.ErrorDomain;
+ test_erroromain_global (err, pkg, global_ns);
+
+
+
- Gee.List<Api.Node> interfaces = global_ns.get_children_by_type (Api.NodeType.INTERFACE, false);
++ Vala.List<Api.Node> classes = global_ns.get_children_by_type (Api.NodeType.CLASS, false);
+ assert (classes.size == 1);
+
+ Api.Class cl = classes.get (0) as Api.Class;
+ test_class_global (cl, pkg, global_ns);
+
+
+
- Gee.List<Api.Node> structs = global_ns.get_children_by_type (Api.NodeType.STRUCT, false);
++ Vala.List<Api.Node> interfaces = global_ns.get_children_by_type (Api.NodeType.INTERFACE, false);
+ assert (interfaces.size == 1);
+
+ Api.Interface iface = interfaces.get (0) as Api.Interface;
+ test_interface_global (iface, pkg, global_ns);
+
+
+
- Gee.List<Api.Node> namespaces = global_ns.get_children_by_type (Api.NodeType.NAMESPACE, false);
++ Vala.List<Api.Node> structs = global_ns.get_children_by_type (Api.NodeType.STRUCT, false);
+ assert (structs.size == 1);
+
+ Api.Struct stru = structs.get (0) as Api.Struct;
+ test_struct_global (stru, pkg, global_ns);
+
+
+
- Gee.List<Api.Node> namespaces = pkg.get_children_by_type (Api.NodeType.NAMESPACE, false);
++ Vala.List<Api.Node> namespaces = global_ns.get_children_by_type (Api.NodeType.NAMESPACE, false);
+
+
+ bool returntest = false;
+ bool paramtest = false;
+ bool versiontest = false;
+
+ foreach (Api.Node node in namespaces) {
+ Api.Namespace ns = node as Api.Namespace;
+ assert (ns != null);
+
+ switch (ns.name) {
+ case "ParamTest":
+ param_test (ns, pkg);
+ paramtest = true;
+ break;
+
+ case "ReturnTest":
+ return_test (ns, pkg);
+ returntest = true;
+ break;
+
+ case "VersionTest":
+ version_test (ns, pkg);
+ versiontest = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (returntest == true);
+ assert (paramtest == true);
+ assert (versiontest == true);
+
+ }
+
+
+ public static void test_package_out (Api.Package pkg) {
+ assert (pkg.is_package == false);
+ assert (pkg.nspace == null);
+ assert (pkg.package == pkg);
+ //assert (pkg.get_full_name () == null);
+
+ // TODO: check .get_source_file ()
+
+
-public static void test_driver (string driver_path) {
- if (!FileUtils.test (driver_path, FileTest.EXISTS)) {
- message ("Driver '%s' is not available", Valadoc.realpath (driver_path));
- assert_not_reached ();
- }
-
++ Vala.List<Api.Node> namespaces = pkg.get_children_by_type (Api.NodeType.NAMESPACE, false);
+ assert (namespaces != null);
+ assert (namespaces.size == 1);
+
+ Api.Namespace global_ns = namespaces.get (0) as Api.Namespace;
+ assert (global_ns != null);
+ assert (global_ns.name == null);
+ assert (global_ns.get_full_name () == null);
+ assert (global_ns.is_deprecated == false);
+ assert (global_ns.get_attributes ().size == 0);
+ assert (global_ns.accessibility == Api.SymbolAccessibility.PUBLIC);
+ assert (global_ns.package == pkg);
+ //assert (global_ns.nspace == null);
+
+ test_global_ns (global_ns, pkg);
+ }
+
+
- TOP_SRC_DIR + "/tests/drivers/api-test.data.vapi"
++public static void test_driver () {
+ var settings = new Valadoc.Settings ();
+ var reporter = new ErrorReporter ();
+
+ settings.source_files = {
- ModuleLoader modules = ModuleLoader.get_instance ();
- var driver = modules.create_driver (driver_path);
++ TOP_SRC_DIR + "/valadoc/tests/drivers/api-test.data.vapi"
+ };
+
+ settings._protected = false;
+ settings._internal = false;
+ settings._private = true;
+ settings.with_deps = false;
+ settings.verbose = false;
+ settings.wiki_directory = null;
+ settings.pkg_name = "out";
+ settings.path = "out";
+
+
- Collection<Api.Package> packages = doctree.get_package_list ();
++ var driver = new Valadoc.Drivers.Driver ();
+ assert (driver != null);
+
+
+ Api.Tree? doctree = driver.build (settings, reporter);
+ assert (reporter.errors == 0);
+ assert (doctree != null);
+
+
+ bool tmp = doctree.create_tree ();
+ assert (tmp);
+
+
++ Vala.Collection<Api.Package> packages = doctree.get_package_list ();
+ assert (packages != null);
+
+ bool glib = false;
+ bool gobj = false;
+ bool test = false;
+
+ foreach (Api.Package pkg in packages) {
+ switch (pkg.name) {
+ case "glib-2.0":
+ assert (pkg.is_package);
+ glib = true;
+ break;
+
+ case "gobject-2.0":
+ assert (pkg.is_package);
+ gobj = true;
+ break;
+
+ case "@out":
+ test_package_out (pkg);
+ test = true;
+ break;
+
+ default:
+ assert_not_reached ();
+ }
+ }
+
+ assert (glib == true);
+ assert (gobj == true);
+ assert (test == true);
+ }
+
+
--- /dev/null
- assert (((Gee.Map) token.attributes).size == 0);
+ /* gtkdoc-scanner.vala
+ *
+ * Copyright (C) 2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc;
+
+
+ void main () {
+ var scanner = new Gtkdoc.Scanner ();
+ scanner.reset ("""<element1>
+ <element2 a="a-val" b="b-val">
+ </element3>
+ <element4 />
+ <element5 a="a-val" b="b-val"/>
+ <!---->
+ <!--
+ AAAA
+ -->
+ foo_bar ()
+ %aaa
+ @param
+ #TypeName
+ myword
+
+ |[]|
+ ::my-signal
+ :my-property
+ """);
+
+ var token = scanner.next ();
+
+ assert (token.type == Gtkdoc.TokenType.XML_OPEN);
+ assert (token.content == "element1");
- assert (((Gee.Map) token.attributes).size == 2);
++ assert (((Vala.Map) token.attributes).size == 0);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.XML_OPEN);
+ assert (token.content == "element2");
+ assert (token.attributes.get ("a") == "a-val");
+ assert (token.attributes.get ("b") == "b-val");
- assert (((Gee.Map) token.attributes).size == 0);
++ assert (((Vala.Map) token.attributes).size == 2);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.XML_CLOSE);
+ assert (token.content == "element3");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.XML_OPEN);
+ assert (token.content == "element4");
- assert (((Gee.Map) token.attributes).size == 2);
++ assert (((Vala.Map) token.attributes).size == 0);
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.XML_CLOSE);
+ assert (token.content == "element4");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.XML_OPEN);
+ assert (token.content == "element5");
+ assert (token.attributes.get ("a") == "a-val");
+ assert (token.attributes.get ("b") == "b-val");
++ assert (((Vala.Map) token.attributes).size == 2);
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.XML_CLOSE);
+ assert (token.content == "element5");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.XML_COMMENT);
+ assert (token.content == "");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.XML_COMMENT);
+ assert (token.content == "");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_FUNCTION);
+ assert (token.content == "foo_bar");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_CONST);
+ assert (token.content == "aaa");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_PARAM);
+ assert (token.content == "param");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_TYPE);
+ assert (token.content == "TypeName");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.WORD);
+ assert (token.content == "myword");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.SPACE);
+ assert (token.content == " ");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_PARAGRAPH);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_SOURCE_OPEN);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_SOURCE_CLOSE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_SIGNAL);
+ assert (token.content == "my-signal");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.GTKDOC_PROPERTY);
+ assert (token.content == "my-property");
+ assert (token.attributes == null);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.NEWLINE);
+
+
+ token = scanner.next ();
+ assert (token.type == Gtkdoc.TokenType.EOF);
+
+ }
--- /dev/null
-export PKG_CONFIG_PATH=$topbuilddir/src/libvaladoc
-export LD_LIBRARY_PATH=$topbuilddir/src/libvaladoc/.libs
+ #!/usr/bin/env bash
+ # testrunner.sh
+ #
+ # Copyright (C) 2006-2008 Jürg Billeter
+ #
+ # This library is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU Lesser General Public
+ # License as published by the Free Software Foundation; either
+ # version 2.1 of the License, or (at your option) any later version.
+ #
+ # This library 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
+ # Lesser General Public License for more details.
+ #
+ # You should have received a copy of the GNU Lesser General Public
+ # License along with this library; if not, write to the Free Software
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ #
+ # Author:
+ # Jürg Billeter <j@bitron.ch>
+
+ builddir=$PWD
+ topbuilddir=$TOPBUILDDIR
+ topsrcdir=$TOPSRCDIR
+ vapidir=$topsrcdir/vapi
+
+ export G_DEBUG=fatal_warnings
-VALAC=valac
-VALAFLAGS="-X -D -X TOP_SRC_DIR=\"$topsrcdir\" --vapidir $topbuilddir/src/libvaladoc --pkg valadoc-1.0 --pkg gee-0.8 --disable-warnings --main main --save-temps -X -g -X -O0 -X -pipe -X -lm -X -Werror=return-type -X -Werror=init-self -X -Werror=implicit -X -Werror=sequence-point -X -Werror=return-type -X -Werror=uninitialized -X -Werror=pointer-arith -X -Werror=int-to-pointer-cast -X -Werror=pointer-to-int-cast -X -Wformat -X -Werror=format-security -X -Werror=format-nonliteral -X -L$topbuilddir/src/libvaladoc/.libs -X -I$topbuilddir/src/libvaladoc $topsrcdir/tests/libvaladoc/parser/generic-scanner.vala $topsrcdir/tests/drivers/generic-api-test.vala"
++export PKG_CONFIG_PATH=$topbuilddir/libvaladoc
++export LD_LIBRARY_PATH=$topbuilddir/gee/.libs:$topbuilddir/libvaladoc/.libs
+
- cat "$topsrcdir/tests/$testfile" >> $SOURCEFILE
++VALAC=$topbuilddir/compiler/valac$EXEEXT
++VALAFLAGS="-X -D -X TOP_SRC_DIR=\"$topsrcdir\" --vapidir $vapidir --pkg libgvc --vapidir $topsrcdir/vala --pkg libvala$PACKAGE_SUFFIX --vapidir $topsrcdir/libvaladoc --pkg valadoc$PACKAGE_SUFFIX --disable-warnings --main main --save-temps -X -g -X -O0 -X -pipe -X -lm -X -Werror=return-type -X -Werror=init-self -X -Werror=implicit -X -Werror=sequence-point -X -Werror=return-type -X -Werror=uninitialized -X -Werror=pointer-arith -X -Werror=int-to-pointer-cast -X -Werror=pointer-to-int-cast -X -Wformat -X -Werror=format-security -X -Werror=format-nonliteral -X -Werror=redundant-decls -X -Werror=int-conversion -X -L$topbuilddir/gee/.libs -X -lgee -X -L$topbuilddir/libvaladoc/.libs -X -lvaladoc$PACKAGE_SUFFIX -X -I$topsrcdir/gee -X -I$topsrcdir/libvaladoc $topsrcdir/valadoc/tests/libvaladoc/parser/generic-scanner.vala"
++
++
++# Incorporate the user's CFLAGS. Matters if the user decided to insert
++# -m32 in CFLAGS, for example.
++for cflag in ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do
++ VALAFLAGS="${VALAFLAGS} -X ${cflag}"
++done
+
+ testdir=_test
+ rm -rf $testdir
+ mkdir $testdir
+ cd $testdir
+
+ echo -n -e "TEST: Building...\033[72G"
+
+ cat << "EOF" > checkall
+ all=0
+ fail=0
+ EOF
+
+ cat << "EOF" > main.vala
+ void main (string[] args) {
+ switch (args[1]) {
+ EOF
+
+ PACKAGES=gio-2.0
+ SOURCEFILES=
+ for testfile in "$@"; do
+ rm -f prepare check
+ echo 'set -e' >> prepare
+
+ case "$testfile" in
+ *.vala)
+ testpath=${testfile/.vala/}
+ ns=${testpath//\//.}
+ ns=${ns//-/_}
+ SOURCEFILE=$ns.vala
+ SOURCEFILES="$SOURCEFILES $SOURCEFILE"
+
+ echo " case \"/$testpath\": $ns.main (); break;" >> main.vala
+ echo "namespace $ns {" > $SOURCEFILE
++ cat "$topsrcdir/valadoc/tests/$testfile" >> $SOURCEFILE
+ echo "}" >> $SOURCEFILE
+
+ echo "./test$EXEEXT /$testpath" > check
+ ;;
+ esac
+
+ cat prepare check > $ns.check
+ cat << EOF >> checkall
+ echo -n -e " /$testpath: \033[72G"
+ ((all++))
+ if bash $ns.check &>log; then
+ echo -e "\033[0;32mOK\033[m"
+ else
+ ((fail++))
+ echo -e "\033[0;31mFAIL\033[m"
+ cat log
+ fi
+ EOF
+ done
+
+ cat << "EOF" >> checkall
+ if [ $fail -eq 0 ]; then
+ echo "All $all tests passed"
+ else
+ echo "$fail of $all tests failed"
+ exit 1
+ fi
+ EOF
+
+ cat << "EOF" >> main.vala
+ default: assert_not_reached ();
+ }
+ }
+ EOF
+
+ cat $SOURCEFILES >> main.vala
+
+ if $VALAC $VALAFLAGS -o test$EXEEXT $([ -z "$PACKAGES" ] || echo $PACKAGES | xargs -n 1 echo -n " --pkg") main.vala &>log; then
+ echo -e "\033[0;32mOK\033[m"
+ else
+ echo -e "\033[0;31mFAIL\033[m"
+ cat log
+
+ cd $builddir
+ exit 1
+ fi
+
+ if bash checkall; then
+ cd $builddir
+ rm -rf $testdir
+ else
+ cd $builddir
+ exit 1
+ fi
+
--- /dev/null
-using Gee;
-
+ /* treebuilder.vala
+ *
+ * Copyright (C) 2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+
+ using Valadoc.Api;
- private ArrayList<PackageMetaData> packages = new ArrayList<PackageMetaData> ();
+
+ /**
+ * Creates an simpler, minimized, more abstract AST for valacs AST.
+ */
+ public class Valadoc.Drivers.TreeBuilder : Vala.CodeVisitor {
- private HashMap<Vala.SourceFile, SourceFile> files = new HashMap<Vala.SourceFile, SourceFile> ();
- private HashMap<Vala.Symbol, Symbol> symbol_map = new HashMap<Vala.Symbol, Symbol> ();
++ private Vala.ArrayList<PackageMetaData> packages = new Vala.ArrayList<PackageMetaData> ();
+ private PackageMetaData source_package;
+
- public HashMap<Vala.Symbol, Symbol> get_symbol_map () {
++ private Vala.HashMap<Vala.SourceFile, SourceFile> files = new Vala.HashMap<Vala.SourceFile, SourceFile> ();
++ private Vala.HashMap<Vala.Symbol, Symbol> symbol_map = new Vala.HashMap<Vala.Symbol, Symbol> ();
+
+ private ErrorReporter reporter;
+ private Settings settings;
+
+ private Api.Node current_node;
+ private Api.Tree tree;
+
+ private Valadoc.Api.Class glib_error = null;
+
+
+ //
+ // Accessors
+ //
+
+ public Api.Class get_glib_error () {
+ return glib_error;
+ }
+
- public HashMap<Vala.Namespace, Namespace> namespaces = new HashMap<Vala.Namespace, Namespace> ();
- public ArrayList<Vala.SourceFile> files = new ArrayList<Vala.SourceFile> ();
++ public Vala.HashMap<Vala.Symbol, Symbol> get_symbol_map () {
+ return symbol_map;
+ }
+
+
+ //
+ //
+ //
+
+ private class PackageMetaData {
+ public Package package;
- for (int i = 2; i <= 36; i += 2) {
++ public Vala.HashMap<Vala.Namespace, Namespace> namespaces = new Vala.HashMap<Vala.Namespace, Namespace> ();
++ public Vala.ArrayList<Vala.SourceFile> files = new Vala.ArrayList<Vala.SourceFile> ();
+
+ public PackageMetaData (Package package) {
+ this.package = package;
+ }
+
+ public Namespace get_namespace (Vala.Namespace vns, SourceFile file) {
+ Namespace? ns = namespaces.get (vns);
+ if (ns != null) {
+ return ns;
+ }
+
+ // find documentation comment if existing:
+ SourceComment? comment = null;
+ if (vns.source_reference != null) {
+ foreach (Vala.Comment c in vns.get_comments()) {
+ if (c.source_reference.file == file.data ||
+ (c.source_reference.file.file_type == Vala.SourceFileType.SOURCE
+ && ((Vala.SourceFile) file.data).file_type == Vala.SourceFileType.SOURCE)
+ ) {
+ Vala.SourceReference pos = c.source_reference;
+ if (c is Vala.GirComment) {
+ comment = new GirSourceComment (c.content,
+ file,
+ pos.begin.line,
+ pos.begin.column,
+ pos.end.line,
+ pos.end.column);
+ } else {
+ comment = new SourceComment (c.content,
+ file,
+ pos.begin.line,
+ pos.begin.column,
+ pos.end.line,
+ pos.end.column);
+ }
+ break;
+ }
+ }
+ }
+
+ // find parent if existing
+ var parent_vns = vns.parent_symbol;
+
+ if (parent_vns == null) {
+ ns = new Namespace (package, file, vns.name, comment, vns);
+ package.add_child (ns);
+ } else {
+ Namespace parent_ns = get_namespace ((Vala.Namespace) parent_vns, file);
+ ns = new Namespace (parent_ns, file, vns.name, comment, vns);
+ parent_ns.add_child (ns);
+ }
+
+ namespaces.set (vns, ns);
+ return ns;
+ }
+
+ public void register_source_file (Vala.SourceFile file) {
+ files.add (file);
+ }
+
+ public bool is_package_for_file (Vala.SourceFile source_file) {
+ if (source_file.file_type == Vala.SourceFileType.SOURCE && !package.is_package) {
+ return true;
+ }
+
+ return files.contains (source_file);
+ }
+ }
+
+
+ //
+ // Type constructor translation helpers:
+ //
+
+ private Pointer create_pointer (Vala.PointerType vtyperef, Item parent, Api.Node caller) {
+ Pointer ptr = new Pointer (parent, vtyperef);
+
+ Vala.DataType vntype = vtyperef.base_type;
+ if (vntype is Vala.PointerType) {
+ ptr.data_type = create_pointer ((Vala.PointerType) vntype, ptr, caller);
+ } else if (vntype is Vala.ArrayType) {
+ ptr.data_type = create_array ((Vala.ArrayType) vntype, ptr, caller);
+ } else {
+ ptr.data_type = create_type_reference (vntype, ptr, caller);
+ }
+
+ return ptr;
+ }
+
+ private Api.Array create_array (Vala.ArrayType vtyperef, Item parent, Api.Node caller) {
+ Api.Array arr = new Api.Array (parent, vtyperef);
+
+ Vala.DataType vntype = vtyperef.element_type;
+ if (vntype is Vala.ArrayType) {
+ arr.data_type = create_type_reference (vntype, arr, caller);
+ } else {
+ arr.data_type = create_type_reference (vntype, arr, caller);
+ }
+
+ return arr;
+ }
+
+ private TypeReference create_type_reference (Vala.DataType? vtyperef, Item parent, Api.Node caller) {
+ bool is_nullable = vtyperef != null
+ && vtyperef.nullable
+ && !(vtyperef is Vala.GenericType)
+ && !(vtyperef is Vala.PointerType);
+ string? signature = (vtyperef != null
+ && vtyperef.data_type != null)? Vala.GVariantModule.get_dbus_signature (vtyperef.data_type) : null;
+ bool pass_ownership = type_reference_pass_ownership (vtyperef);
+ Ownership ownership = get_type_reference_ownership (vtyperef);
+ bool is_dynamic = vtyperef != null && vtyperef.is_dynamic;
+
+ TypeReference type_ref = new TypeReference (parent,
+ ownership,
+ pass_ownership,
+ is_dynamic,
+ is_nullable,
+ signature,
+ vtyperef);
+
+ if (vtyperef is Vala.PointerType) {
+ type_ref.data_type = create_pointer ((Vala.PointerType) vtyperef, type_ref, caller);
+ } else if (vtyperef is Vala.ArrayType) {
+ type_ref.data_type = create_array ((Vala.ArrayType) vtyperef, type_ref, caller);
+ //} else if (vtyperef is Vala.GenericType) {
+ // type_ref.data_type = new TypeParameter (caller,
+ // caller.get_source_file (),
+ // ((Vala.GenericType) vtyperef).type_parameter.name,
+ // vtyperef);
+ }
+
+ // type parameters:
+ if (vtyperef != null) {
+ foreach (Vala.DataType vdtype in vtyperef.get_type_arguments ()) {
+ var type_param = create_type_reference (vdtype, type_ref, caller);
+ type_ref.add_type_argument (type_param);
+ }
+ }
+
+ return type_ref;
+ }
+
+
+
+ //
+ // Translation helpers:
+ //
+
+ private void process_attributes (Api.Symbol parent, GLib.List<Vala.Attribute> lst) {
+ // attributes without arguments:
+ string[] attributes = {
+ "ReturnsModifiedPointer",
+ "DestroysInstance",
+ "GenericAccessors",
+ "NoAccessorMethod",
+ "NoArrayLength",
+ "Experimental",
+ "Diagnostics",
+ "PrintfFormat",
+ "PointerType",
+ "ScanfFormat",
+ "ThreadLocal",
+ "SimpleType",
+ "HasEmitter",
+ "ModuleInit",
+ "NoWrapper",
+ "Immutable",
+ "ErrorBase",
+ "NoReturn",
+ "NoThrow",
+ "Compact",
+ "Assert",
+ "Flags"
+ };
+
+ string? tmp = "";
+
+ foreach (Vala.Attribute att in lst) {
+ if (att.name == "CCode" && (tmp = att.args.get ("has_target")) != null && tmp == "false") {
+ Attribute new_attribute = new Attribute (parent, parent.get_source_file (), att.name, att);
+ new_attribute.add_boolean ("has_target", false, att);
+ parent.add_attribute (new_attribute);
+ } else if (att.name == "Version") {
+ Attribute new_attribute = new Attribute (parent, parent.get_source_file (), att.name, att);
+ if ((tmp = att.args.get ("deprecated")) != null) {
+ new_attribute.add_boolean ("deprecated", bool.parse (tmp), att);
+ }
+ if ((tmp = att.args.get ("since")) != null) {
+ new_attribute.add_string ("since", tmp, att);
+ }
+ if ((tmp = att.args.get ("deprecated_since")) != null) {
+ new_attribute.add_string ("deprecated_since", tmp, att);
+ if (att.args.get ("deprecated") == null) {
+ new_attribute.add_boolean ("deprecated", true, att);
+ }
+ }
+ if ((tmp = att.args.get ("replacement")) != null) {
+ new_attribute.add_string ("replacement", tmp, att);
+ }
+ parent.add_attribute (new_attribute);
+ } else if (att.name == "Deprecated") {
+ Attribute new_attribute = new Attribute (parent, parent.get_source_file (), att.name, att);
+ if ((tmp = att.args.get ("since")) != null) {
+ new_attribute.add_string ("since", tmp, att);
+ }
+ if ((tmp = att.args.get ("replacement")) != null) {
+ new_attribute.add_string ("replacement", tmp, att);
+ }
+ parent.add_attribute (new_attribute);
+ } else if (att.name in attributes) {
+ Attribute new_attribute = new Attribute (parent, parent.get_source_file (), att.name, att);
+ parent.add_attribute (new_attribute);
+ }
+ }
+ }
+
+ private string? get_ccode_type_id (Vala.CodeNode node) {
+ return Vala.CCodeBaseModule.get_ccode_type_id (node);
+ }
+
+ private bool is_reference_counting (Vala.TypeSymbol sym) {
+ return Vala.CCodeBaseModule.is_reference_counting (sym);
+ }
+
+ private string? get_ref_function (Vala.Class sym) {
+ return Vala.CCodeBaseModule.get_ccode_ref_function (sym);
+ }
+
+ private string? get_unref_function (Vala.Class sym) {
+ return Vala.CCodeBaseModule.get_ccode_unref_function (sym);
+ }
+
+ private string? get_finalize_function_name (Vala.Class element) {
+ if (!element.is_fundamental ()) {
+ return null;
+ }
+
+ return "%s_finalize".printf (Vala.CCodeBaseModule.get_ccode_lower_case_name (element, null));
+ }
+
+ private string? get_free_function_name (Vala.Class element) {
+ if (!element.is_compact) {
+ return null;
+ }
+
+ return Vala.CCodeBaseModule.get_ccode_free_function (element);
+ }
+
+ private string? get_finish_name (Vala.Method m) {
+ return Vala.CCodeBaseModule.get_ccode_finish_name (m);
+ }
+
+ private string? get_take_value_function (Vala.Class sym) {
+ return Vala.CCodeBaseModule.get_ccode_take_value_function (sym);
+ }
+
+ private string? get_get_value_function (Vala.Class sym) {
+ return Vala.CCodeBaseModule.get_ccode_get_value_function (sym);
+ }
+
+ private string? get_set_value_function (Vala.Class sym) {
+ return Vala.CCodeBaseModule.get_ccode_set_value_function (sym);
+ }
+
+
+ private string? get_param_spec_function (Vala.CodeNode sym) {
+ return Vala.CCodeBaseModule.get_ccode_param_spec_function (sym);
+ }
+
+ private string? get_dup_function (Vala.TypeSymbol sym) {
+ return Vala.CCodeBaseModule.get_ccode_dup_function (sym);
+ }
+
+ private string? get_copy_function (Vala.TypeSymbol sym) {
+ return Vala.CCodeBaseModule.get_ccode_copy_function (sym);
+ }
+
+ private string? get_destroy_function (Vala.TypeSymbol sym) {
+ return Vala.CCodeBaseModule.get_ccode_destroy_function (sym);
+ }
+
+ private string? get_free_function (Vala.TypeSymbol sym) {
+ return Vala.CCodeBaseModule.get_ccode_free_function (sym);
+ }
+
+ private string? get_cname (Vala.Symbol symbol) {
+ return Vala.CCodeBaseModule.get_ccode_name (symbol);
+ }
+
+ private SourceComment? create_comment (Vala.Comment? comment) {
+ if (comment != null) {
+ Vala.SourceReference pos = comment.source_reference;
+ SourceFile file = files.get (pos.file);
+ if (comment is Vala.GirComment) {
+ var tmp = new GirSourceComment (comment.content,
+ file,
+ pos.begin.line,
+ pos.begin.column,
+ pos.end.line,
+ pos.end.column);
+ if (((Vala.GirComment) comment).return_content != null) {
+ Vala.SourceReference return_pos = ((Vala.GirComment) comment).return_content.source_reference;
+ tmp.return_comment = new SourceComment (((Vala.GirComment) comment).return_content.content,
+ file,
+ return_pos.begin.line,
+ return_pos.begin.column,
+ return_pos.end.line,
+ return_pos.end.column);
+ }
+
+ Vala.MapIterator<string, Vala.Comment> it = ((Vala.GirComment) comment).parameter_iterator ();
+ while (it.next ()) {
+ Vala.Comment vala_param = it.get_value ();
+ Vala.SourceReference param_pos = vala_param.source_reference;
+ var param_comment = new SourceComment (vala_param.content,
+ file,
+ param_pos.begin.line,
+ param_pos.begin.column,
+ param_pos.end.line,
+ param_pos.end.column);
+ tmp.add_parameter_content (it.get_key (), param_comment);
+ }
+ return tmp;
+ } else {
+ return new SourceComment (comment.content,
+ file,
+ pos.begin.line,
+ pos.begin.column,
+ pos.end.line,
+ pos.end.column);
+ }
+ }
+
+ return null;
+ }
+
+ private string get_method_name (Vala.Method element) {
+ if (element is Vala.CreationMethod) {
+ if (element.name == ".new") {
+ return element.parent_symbol.name;
+ } else {
+ return element.parent_symbol.name + "." + element.name;
+ }
+ }
+
+ return element.name;
+ }
+
+ private string? get_quark_macro_name (Vala.ErrorDomain element) {
+ return Vala.CCodeBaseModule.get_ccode_upper_case_name (element, null);
+ }
+
+ private string? get_private_cname (Vala.Class element) {
+ if (element.is_compact) {
+ return null;
+ }
+
+ string? cname = get_cname (element);
+ return (cname != null)? cname + "Private" : null;
+ }
+
+ private string? get_class_macro_name (Vala.Class element) {
+ if (element.is_compact) {
+ return null;
+ }
+
+ return "%s_GET_CLASS".printf (Vala.CCodeBaseModule.get_ccode_upper_case_name (element, null));
+ }
+
+ private string? get_class_type_macro_name (Vala.Class element) {
+ if (element.is_compact) {
+ return null;
+ }
+
+ return "%s_CLASS".printf (Vala.CCodeBaseModule.get_ccode_upper_case_name (element, null));
+ }
+
+ private string? get_is_type_macro_name (Vala.TypeSymbol element) {
+ string? name = Vala.CCodeBaseModule.get_ccode_type_check_function (element);
+ return (name != null && name != "")? name : null;
+ }
+
+ private string? get_is_class_type_macro_name (Vala.TypeSymbol element) {
+ string? name = get_is_type_macro_name (element);
+ return (name != null)? name + "_CLASS" : null;
+ }
+
+ private string? get_type_function_name (Vala.TypeSymbol element) {
+ if ((element is Vala.Class
+ && ((Vala.Class) element).is_compact)
+ || element is Vala.ErrorDomain
+ || element is Vala.Delegate)
+ {
+ return null;
+ }
+
+ return "%s_get_type".printf (Vala.CCodeBaseModule.get_ccode_lower_case_name (element, null));
+ }
+
+ private string? get_type_macro_name (Vala.TypeSymbol element) {
+ if ((element is Vala.Class
+ && ((Vala.Class) element).is_compact)
+ || element is Vala.ErrorDomain
+ || element is Vala.Delegate)
+ {
+ return null;
+ }
+
+ return Vala.CCodeBaseModule.get_ccode_type_id (element);
+ }
+
+ private string? get_type_cast_macro_name (Vala.TypeSymbol element) {
+ if ((element is Vala.Class
+ && !((Vala.Class) element).is_compact)
+ || element is Vala.Interface)
+ {
+ return Vala.CCodeBaseModule.get_ccode_upper_case_name (element, null);
+ } else {
+ return null;
+ }
+ }
+
+ private string? get_interface_macro_name (Vala.Interface element) {
+ return "%s_GET_INTERFACE".printf (Vala.CCodeBaseModule.get_ccode_upper_case_name (element, null));
+ }
+
+ private string get_quark_function_name (Vala.ErrorDomain element) {
+ return Vala.CCodeBaseModule.get_ccode_lower_case_prefix (element) + "quark";
+ }
+
+ private PackageMetaData? get_package_meta_data (Package pkg) {
+ foreach (PackageMetaData data in packages) {
+ if (data.package == pkg) {
+ return data;
+ }
+ }
+
+ return null;
+ }
+
+ private PackageMetaData register_package (Package package) {
+ PackageMetaData meta_data = new PackageMetaData (package);
+ tree.add_package (package);
+ packages.add (meta_data);
+ return meta_data;
+ }
+
+ private SourceFile register_source_file (PackageMetaData meta_data, Vala.SourceFile source_file) {
+ SourceFile file = new SourceFile (meta_data.package,
+ source_file.get_relative_filename (),
+ source_file.get_csource_filename (),
+ source_file);
+ files.set (source_file, file);
+
+ meta_data.register_source_file (source_file);
+ return file;
+ }
+
+ private SourceFile? get_source_file (Vala.Symbol symbol) {
+ Vala.SourceReference source_ref = symbol.source_reference;
+ if (source_ref == null) {
+ return null;
+ }
+
+ SourceFile? file = files.get (source_ref.file);
+ assert (file != null);
+ return file;
+ }
+
+ private Package? find_package_for_file (Vala.SourceFile source_file) {
+ foreach (PackageMetaData pkg in this.packages) {
+ if (pkg.is_package_for_file (source_file)) {
+ return pkg.package;
+ }
+ }
+
+ return null;
+ }
+
+
+ private Namespace get_namespace (Package pkg, Vala.Symbol symbol, SourceFile? file) {
+ // Find the closest namespace in our vala-tree
+ Vala.Symbol namespace_symbol = symbol;
+ while (!(namespace_symbol is Vala.Namespace)) {
+ namespace_symbol = namespace_symbol.parent_symbol;
+ }
+
+ PackageMetaData? meta_data = get_package_meta_data (pkg);
+ assert (meta_data != null);
+
+ return meta_data.get_namespace ((Vala.Namespace) namespace_symbol, file);
+ }
+
+ private MethodBindingType get_method_binding_type (Vala.Method element) {
+ if (element.is_inline) {
+ return MethodBindingType.INLINE;
+ } else if (element.is_abstract) {
+ return MethodBindingType.ABSTRACT;
+ } else if (element.is_virtual) {
+ return MethodBindingType.VIRTUAL;
+ } else if (element.overrides) {
+ return MethodBindingType.OVERRIDE;
+ } else if (element.is_inline) {
+ return MethodBindingType.INLINE;
+ } else if (element.binding != Vala.MemberBinding.INSTANCE) {
+ return MethodBindingType.STATIC;
+ }
+ return MethodBindingType.UNMODIFIED;
+ }
+
+
+ private SymbolAccessibility get_access_modifier(Vala.Symbol symbol) {
+ switch (symbol.access) {
+ case Vala.SymbolAccessibility.PROTECTED:
+ return SymbolAccessibility.PROTECTED;
+
+ case Vala.SymbolAccessibility.INTERNAL:
+ return SymbolAccessibility.INTERNAL;
+
+ case Vala.SymbolAccessibility.PRIVATE:
+ return SymbolAccessibility.PRIVATE;
+
+ case Vala.SymbolAccessibility.PUBLIC:
+ return SymbolAccessibility.PUBLIC;
+
+ default:
+ error ("Unknown symbol accessibility modifier found");
+ }
+ }
+
+ private PropertyAccessorType get_property_accessor_type (Vala.PropertyAccessor element) {
+ if (element.construction) {
+ if (element.writable) {
+ return (PropertyAccessorType.CONSTRUCT | PropertyAccessorType.SET);
+ }
+ return PropertyAccessorType.CONSTRUCT;
+ } else if (element.writable) {
+ return PropertyAccessorType.SET;
+ } else if (element.readable) {
+ return PropertyAccessorType.GET;
+ }
+
+ error ("Unknown symbol accessibility type");
+ }
+
+ private bool type_reference_pass_ownership (Vala.DataType? element) {
+ if (element == null) {
+ return false;
+ }
+
+ weak Vala.CodeNode? node = element.parent_node;
+ if (node == null) {
+ return false;
+ }
+ if (node is Vala.Parameter) {
+ return (((Vala.Parameter)node).direction == Vala.ParameterDirection.IN &&
+ ((Vala.Parameter)node).variable_type.value_owned);
+ }
+ if (node is Vala.Property) {
+ return ((Vala.Property)node).property_type.value_owned;
+ }
+
+ return false;
+ }
+
+ private bool is_type_reference_unowned (Vala.DataType? element) {
+ if (element == null) {
+ return false;
+ }
+
+ // non ref counted types are weak, not unowned
+ if (element.data_type is Vala.TypeSymbol
+ && is_reference_counting ((Vala.TypeSymbol) element.data_type) == true)
+ {
+ return false;
+ }
+
+ // FormalParameters are weak by default
+ return (element.parent_node is Vala.Parameter == false)
+ ? element.is_weak ()
+ : false;
+ }
+
+ private bool is_type_reference_owned (Vala.DataType? element) {
+ if (element == null) {
+ return false;
+ }
+
+ weak Vala.CodeNode parent = element.parent_node;
+
+ // parameter:
+ if (parent is Vala.Parameter) {
+ if (((Vala.Parameter)parent).direction != Vala.ParameterDirection.IN) {
+ return false;
+ }
+ return ((Vala.Parameter)parent).variable_type.value_owned;
+ }
+
+ return false;
+ }
+
+ private bool is_type_reference_weak (Vala.DataType? element) {
+ if (element == null) {
+ return false;
+ }
+
+ // non ref counted types are unowned, not weak
+ if (element.data_type is Vala.TypeSymbol
+ && is_reference_counting ((Vala.TypeSymbol) element.data_type) == false)
+ {
+ return false;
+ }
+
+ // arrays are unowned, not weak
+ if (element is Vala.ArrayType) {
+ return false;
+ }
+
+ // FormalParameters are weak by default
+ return (element.parent_node is Vala.Parameter == false)? element.is_weak () : false;
+ }
+
+ private Ownership get_type_reference_ownership (Vala.DataType? element) {
+ if (is_type_reference_owned (element)) {
+ return Ownership.OWNED;
+ } else if (is_type_reference_weak (element)) {
+ return Ownership.WEAK;
+ } else if (is_type_reference_unowned (element)) {
+ return Ownership.UNOWNED;
+ }
+
+ return Ownership.DEFAULT;
+ }
+
+ private Ownership get_property_ownership (Vala.PropertyAccessor element) {
+ if (element.value_type.value_owned) {
+ return Ownership.OWNED;
+ }
+
+ // the exact type (weak, unowned) does not matter
+ return Ownership.UNOWNED;
+ }
+
+ private PropertyBindingType get_property_binding_type (Vala.Property element) {
+ if (element.is_abstract) {
+ return PropertyBindingType.ABSTRACT;
+ } else if (element.is_virtual) {
+ return PropertyBindingType.VIRTUAL;
+ } else if (element.overrides) {
+ return PropertyBindingType.OVERRIDE;
+ }
+
+ return PropertyBindingType.UNMODIFIED;
+ }
+
+ private FormalParameterType get_formal_parameter_type (Vala.Parameter element) {
+ if (element.direction == Vala.ParameterDirection.OUT) {
+ return FormalParameterType.OUT;
+ } else if (element.direction == Vala.ParameterDirection.REF) {
+ return FormalParameterType.REF;
+ } else if (element.direction == Vala.ParameterDirection.IN) {
+ return FormalParameterType.IN;
+ }
+
+ error ("Unknown formal parameter type");
+ }
+
+
+ //
+ // Vala tree creation:
+ //
+
+ private string get_package_name (string path) {
+ string file_name = Path.get_basename (path);
+ return file_name.substring (0, file_name.last_index_of_char ('.'));
+ }
+
+ private bool add_package (Vala.CodeContext context, string pkg) {
+ // ignore multiple occurences of the same package
+ if (context.has_package (pkg)) {
+ return true;
+ }
+
+ string vapi_name = pkg + ".vapi";
+ string gir_name = pkg + ".gir";
+ foreach (string source_file in settings.source_files) {
+ string basename = Path.get_basename (source_file);
+ if (basename == vapi_name || basename == gir_name) {
+ return true;
+ }
+ }
+
+
+ var package_path = context.get_vapi_path (pkg) ?? context.get_gir_path (pkg);
+ if (package_path == null) {
+ Vala.Report.error (null, "Package `%s' not found in specified Vala API directories or GObject-Introspection GIR directories".printf (pkg));
+ return false;
+ }
+
+ context.add_package (pkg);
+
+ var vfile = new Vala.SourceFile (context, Vala.SourceFileType.PACKAGE, package_path);
+ context.add_source_file (vfile);
+ Package vdpkg = new Package (pkg, true, null);
+ register_source_file (register_package (vdpkg), vfile);
+
+ add_deps (context, Path.build_filename (Path.get_dirname (package_path), "%s.deps".printf (pkg)), pkg);
+ return true;
+ }
+
+ private void add_deps (Vala.CodeContext context, string file_path, string pkg_name) {
+ if (FileUtils.test (file_path, FileTest.EXISTS)) {
+ try {
+ string deps_content;
+ ulong deps_len;
+ FileUtils.get_contents (file_path, out deps_content, out deps_len);
+ foreach (string dep in deps_content.split ("\n")) {
+ dep = dep.strip ();
+ if (dep != "") {
+ if (!add_package (context, dep)) {
+ Vala.Report.error (null, "%s, dependency of %s, not found in specified Vala API directories".printf (dep, pkg_name));
+ }
+ }
+ }
+ } catch (FileError e) {
+ Vala.Report.error (null, "Unable to read dependency file: %s".printf (e.message));
+ }
+ }
+ }
+
+ /**
+ * Adds the specified packages to the list of used packages.
+ *
+ * @param context The code context
+ * @param packages a list of package names
+ */
+ private void add_depencies (Vala.CodeContext context, string[] packages) {
+ foreach (string package in packages) {
+ if (!add_package (context, package)) {
+ Vala.Report.error (null, "Package `%s' not found in specified Vala API directories or GObject-Introspection GIR directories".printf (package));
+ }
+ }
+ }
+
+ /**
+ * Add the specified source file to the context. Only .vala, .vapi, .gs,
+ * and .c files are supported.
+ */
+ private void add_documented_files (Vala.CodeContext context, string[] sources) {
+ if (sources == null) {
+ return;
+ }
+
+ foreach (string source in sources) {
+ if (FileUtils.test (source, FileTest.EXISTS)) {
+ var rpath = realpath (source);
+ if (source.has_suffix (".vala") || source.has_suffix (".gs")) {
+ var source_file = new Vala.SourceFile (context, Vala.SourceFileType.SOURCE, rpath);
+
+ if (source_package == null) {
+ source_package = register_package (new Package (settings.pkg_name, false, null));
+ }
+
+ register_source_file (source_package, source_file);
+
+ if (context.profile == Vala.Profile.GOBJECT) {
+ // import the GLib namespace by default (namespace of backend-specific standard library)
+ var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib", null));
+ source_file.add_using_directive (ns_ref);
+ context.root.add_using_directive (ns_ref);
+ }
+
+ context.add_source_file (source_file);
+ } else if (source.has_suffix (".vapi") || source.has_suffix (".gir")) {
+ string file_name = get_package_name (source);
+
+ var vfile = new Vala.SourceFile (context, Vala.SourceFileType.PACKAGE, rpath);
+ context.add_source_file (vfile);
+
+ if (source_package == null) {
+ source_package = register_package (new Package (settings.pkg_name, false, null));
+ }
+
+ register_source_file (source_package, vfile);
+
+ add_deps (context, Path.build_filename (Path.get_dirname (source), "%s.deps".printf (file_name)), file_name);
+ } else if (source.has_suffix (".c")) {
+ context.add_c_source_file (rpath);
+ tree.add_external_c_files (rpath);
+ } else {
+ Vala.Report.error (null, "%s is not a supported source file type. Only .vala, .vapi, .gs, and .c files are supported.".printf (source));
+ }
+ } else {
+ Vala.Report.error (null, "%s not found".printf (source));
+ }
+ }
+ }
+
+ private Vala.CodeContext create_valac_tree (Settings settings) {
+ // init context:
+ var context = new Vala.CodeContext ();
+ Vala.CodeContext.push (context);
+
+
+ // settings:
+ context.experimental = settings.experimental;
+ context.experimental_non_null = settings.experimental || settings.experimental_non_null;
+ context.vapi_directories = settings.vapi_directories;
+ context.report.enable_warnings = settings.verbose;
+ context.metadata_directories = settings.metadata_directories;
+ context.gir_directories = settings.gir_directories;
+
+ if (settings.basedir == null) {
+ context.basedir = realpath (".");
+ } else {
+ context.basedir = realpath (settings.basedir);
+ }
+
+ if (settings.directory != null) {
+ context.directory = realpath (settings.directory);
+ } else {
+ context.directory = context.basedir;
+ }
+
+
+ // add default packages:
+ if (settings.profile == "gobject-2.0" || settings.profile == "gobject" || settings.profile == null) {
+ context.profile = Vala.Profile.GOBJECT;
+ context.add_define ("GOBJECT");
+ }
+
+
+ if (settings.defines != null) {
+ foreach (string define in settings.defines) {
+ context.add_define (define);
+ }
+ }
+
- && files.has_key (vfile) == false)
++ for (int i = 2; i <= 38; i += 2) {
+ context.add_define ("VALA_0_%d".printf (i));
+ }
+
+ if (context.profile == Vala.Profile.GOBJECT) {
+ int glib_major = 2;
+ int glib_minor = 24;
+
+ context.target_glib_major = glib_major;
+ context.target_glib_minor = glib_minor;
+ if (context.target_glib_major != 2) {
+ Vala.Report.error (null, "This version of valac only supports GLib 2");
+ }
+
+ if (settings.target_glib != null && settings.target_glib.scanf ("%d.%d", out glib_major, out glib_minor) != 2) {
+ Vala.Report.error (null, "Invalid format for --target-glib");
+ }
+
+ context.target_glib_major = glib_major;
+ context.target_glib_minor = glib_minor;
+ if (context.target_glib_major != 2) {
+ Vala.Report.error (null, "This version of valac only supports GLib 2");
+ }
+
+ for (int i = 16; i <= glib_minor; i += 2) {
+ context.add_define ("GLIB_2_%d".printf (i));
+ }
+
+ // default packages
+ if (!this.add_package (context, "glib-2.0")) { //
+ Vala.Report.error (null, "glib-2.0 not found in specified Vala API directories");
+ }
+
+ if (!this.add_package (context, "gobject-2.0")) { //
+ Vala.Report.error (null, "gobject-2.0 not found in specified Vala API directories");
+ }
+ }
+
+ // add user defined files:
+ add_depencies (context, settings.packages);
+ if (reporter.errors > 0) {
+ return context;
+ }
+
+ add_documented_files (context, settings.source_files);
+ if (reporter.errors > 0) {
+ return context;
+ }
+
+
+ // parse vala-code:
+ Vala.Parser parser = new Vala.Parser ();
+
+ parser.parse (context);
+ if (context.report.get_errors () > 0) {
+ return context;
+ }
+
+ // parse gir:
+ Vala.GirParser gir_parser = new Vala.GirParser ();
+
+ gir_parser.parse (context);
+ if (context.report.get_errors () > 0) {
+ return context;
+ }
+
+
+
+ // check context:
+ context.check ();
+ if (context.report.get_errors () > 0) {
+ return context;
+ }
+
+ return context;
+ }
+
+
+
+ //
+ // Valadoc tree creation:
+ //
+
+ private void process_children (Api.Node node, Vala.CodeNode element) {
+ Api.Node old_node = current_node;
+ current_node = node;
+ element.accept_children (this);
+ current_node = old_node;
+ }
+
+ private Api.Node get_parent_node_for (Vala.Symbol element) {
+ if (current_node != null) {
+ return current_node;
+ }
+
+ Vala.SourceFile vala_source_file = element.source_reference.file;
+ Package package = find_package_for_file (vala_source_file);
+ SourceFile? source_file = get_source_file (element);
+
+ return get_namespace (package, element, source_file);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_namespace (Vala.Namespace element) {
+ element.accept_children (this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_class (Vala.Class element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ bool is_basic_type = element.base_class == null && element.name == "string";
+
+ Class node = new Class (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ get_private_cname (element),
+ get_class_macro_name (element),
+ get_type_macro_name (element),
+ get_is_type_macro_name (element),
+ get_type_cast_macro_name (element),
+ get_type_function_name (element),
+ get_class_type_macro_name (element),
+ get_is_class_type_macro_name (element),
+ Vala.GDBusModule.get_dbus_name (element),
+ get_ccode_type_id (element),
+ get_param_spec_function (element),
+ get_ref_function (element),
+ get_unref_function (element),
+ get_free_function_name (element),
+ get_finalize_function_name (element),
+ get_take_value_function (element),
+ get_get_value_function (element),
+ get_set_value_function (element),
+ element.is_fundamental (),
+ element.is_abstract,
+ is_basic_type,
+ element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ // relations
+ foreach (Vala.DataType vala_type_ref in element.get_base_types ()) {
+ var type_ref = create_type_reference (vala_type_ref, node, node);
+
+ if (vala_type_ref.data_type is Vala.Interface) {
+ node.add_interface (type_ref);
+ } else if (vala_type_ref.data_type is Vala.Class) {
+ node.base_type = type_ref;
+ }
+ }
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+
+ // save GLib.Error
+ if (glib_error == null && node.get_full_name () == "GLib.Error") {
+ glib_error = node;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_interface (Vala.Interface element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Interface node = new Interface (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ get_type_macro_name (element),
+ get_is_type_macro_name (element),
+ get_type_cast_macro_name (element),
+ get_type_function_name (element),
+ get_interface_macro_name (element),
+ Vala.GDBusModule.get_dbus_name (element),
+ element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ // prerequisites:
+ foreach (Vala.DataType vala_type_ref in element.get_prerequisites ()) {
+ TypeReference type_ref = create_type_reference (vala_type_ref, node, node);
+ if (vala_type_ref.data_type is Vala.Interface) {
+ node.add_interface (type_ref);
+ } else {
+ node.base_type = type_ref;
+ }
+ }
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_struct (Vala.Struct element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ bool is_basic_type = element.base_type == null
+ && (element.is_boolean_type ()
+ || element.is_floating_type ()
+ || element.is_integer_type ());
+
+ Struct node = new Struct (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ get_type_macro_name (element),
+ get_type_function_name (element),
+ get_ccode_type_id (element),
+ get_dup_function (element),
+ get_copy_function (element),
+ get_destroy_function (element),
+ get_free_function (element),
+ is_basic_type,
+ element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ // parent type:
+ Vala.ValueType? basetype = element.base_type as Vala.ValueType;
+ if (basetype != null) {
+ node.base_type = create_type_reference (basetype, node, node);
+ }
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_field (Vala.Field element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Field node = new Field (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ element.binding == Vala.MemberBinding.STATIC,
+ element.is_volatile,
+ element);
+ node.field_type = create_type_reference (element.variable_type, node, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_property (Vala.Property element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Property node = new Property (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ element.nick,
+ Vala.GDBusModule.get_dbus_name_for_member (element),
+ Vala.GDBusModule.is_dbus_visible (element),
+ get_property_binding_type (element),
+ element);
+ node.property_type = create_type_reference (element.property_type, node, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ // Process property type
+ if (element.get_accessor != null) {
+ var accessor = element.get_accessor;
+ node.getter = new PropertyAccessor (node,
+ file,
+ element.name,
+ get_access_modifier (accessor),
+ get_cname (accessor),
+ get_property_accessor_type (accessor),
+ get_property_ownership (accessor),
+ accessor);
+ }
+
+ if (element.set_accessor != null) {
+ var accessor = element.set_accessor;
+ node.setter = new PropertyAccessor (node,
+ file,
+ element.name,
+ get_access_modifier (accessor),
+ get_cname (accessor),
+ get_property_accessor_type (accessor),
+ get_property_ownership (accessor),
+ accessor);
+ }
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_creation_method (Vala.CreationMethod element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Method node = new Method (parent,
+ file,
+ get_method_name (element),
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ Vala.GDBusModule.get_dbus_name_for_member (element),
+ Vala.GDBusModule.dbus_result_name (element),
+ (element.coroutine)? get_finish_name (element) : null,
+ get_method_binding_type (element),
+ element.coroutine,
+ Vala.GDBusModule.is_dbus_visible (element),
+ element is Vala.CreationMethod,
+ element);
+ node.return_type = create_type_reference (element.return_type, node, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_method (Vala.Method element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Method node = new Method (parent,
+ file,
+ get_method_name (element),
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ Vala.GDBusModule.get_dbus_name_for_member (element),
+ Vala.GDBusModule.dbus_result_name (element),
+ (element.coroutine)? get_finish_name (element) : null,
+ get_method_binding_type (element),
+ element.coroutine,
+ Vala.GDBusModule.is_dbus_visible (element),
+ element is Vala.CreationMethod,
+ element);
+ node.return_type = create_type_reference (element.return_type, node, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_signal (Vala.Signal element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Api.Signal node = new Api.Signal (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ (element.default_handler != null)? get_cname (element.default_handler) : null,
+ Vala.GDBusModule.get_dbus_name_for_member (element),
+ Vala.GDBusModule.is_dbus_visible (element),
+ element.is_virtual,
+ element);
+ node.return_type = create_type_reference (element.return_type, node, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_delegate (Vala.Delegate element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Delegate node = new Delegate (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ !element.has_target,
+ element);
+ node.return_type = create_type_reference (element.return_type, node, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_enum (Vala.Enum element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Symbol node = new Enum (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ get_type_macro_name (element),
+ get_type_function_name (element),
+ element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_enum_value (Vala.EnumValue element) {
+ Api.Enum parent = (Enum) get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Symbol node = new Api.EnumValue (parent,
+ file,
+ element.name,
+ comment,
+ get_cname (element),
+ element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_constant (Vala.Constant element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Constant node = new Constant (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ element);
+ node.constant_type = create_type_reference (element.type_reference, node, node);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_error_domain (Vala.ErrorDomain element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ SourceComment? comment = create_comment (element.comment);
+
+ Symbol node = new ErrorDomain (parent,
+ file,
+ element.name,
+ get_access_modifier (element),
+ comment,
+ get_cname (element),
+ get_quark_macro_name (element),
+ get_quark_function_name (element),
+ Vala.GDBusModule.get_dbus_name (element),
+ element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_error_code (Vala.ErrorCode element) {
+ Api.ErrorDomain parent = (ErrorDomain) get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+ if (file == null) {
+ file = parent.get_source_file ();
+ }
+
+ SourceComment? comment = create_comment (element.comment);
+
+ Symbol node = new Api.ErrorCode (parent,
+ file,
+ element.name,
+ comment,
+ get_cname (element),
+ Vala.GDBusModule.get_dbus_name_for_member (element),
+ element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_attributes (node, element.attributes);
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_type_parameter (Vala.TypeParameter element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+
+ Symbol node = new TypeParameter (parent,
+ file,
+ element.name,
+ element);
+ symbol_map.set (element, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public override void visit_formal_parameter (Vala.Parameter element) {
+ Api.Node parent = get_parent_node_for (element);
+ SourceFile? file = get_source_file (element);
+
+ FormalParameter node = new FormalParameter (parent,
+ file,
+ element.name,
+ get_access_modifier(element),
+ get_formal_parameter_type (element),
+ element.ellipsis,
+ element);
+ node.parameter_type = create_type_reference (element.variable_type, node, node);
+ parent.add_child (node);
+
+ process_children (node, element);
+ }
+
+
+ //
+ // startpoint:
+ //
+
+ public Api.Tree? build (Settings settings, ErrorReporter reporter) {
+ this.settings = settings;
+ this.reporter = reporter;
+
+ this.tree = new Api.Tree (reporter, settings);
+ var context = create_valac_tree (settings);
+ this.tree.data = context;
+
+ reporter.warnings_offset = context.report.get_warnings ();
+ reporter.errors_offset = context.report.get_errors ();
+
+ if (context == null) {
+ return null;
+ }
+
+ // TODO: Register all packages here
+ // register packages included by gir-files
+ foreach (Vala.SourceFile vfile in context.get_source_files ()) {
+ if (vfile.file_type == Vala.SourceFileType.PACKAGE
+ && vfile.get_nodes ().size > 0
++ && files.contains (vfile) == false)
+ {
+ Package vdpkg = new Package (get_package_name (vfile.filename), true, null);
+ register_source_file (register_package (vdpkg), vfile);
+ }
+ }
+
+ context.accept(this);
+
+ return (reporter.errors == 0)? tree : null;
+ }
+ }
+
+
--- /dev/null
-using GLib.Path;
+ /* valadoc.vala
+ *
+ * Copyright (C) 2008-2014 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
-using Config;
-using Gee;
-
-
+ using Valadoc.Importer;
+ using Valadoc;
- private static string gir_directory = null;
+
+ public class ValaDoc : Object {
+ private const string DEFAULT_COLORS = "error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01";
+
+ private static string wikidirectory = null;
+ private static string pkg_version = null;
+ private static string docletpath = null;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] pluginargs;
- pluginpath = ModuleLoader.get_driver_path (driverpath, reporter);
- if (pluginpath == null) {
- return null;
- }
-
- driver = modules.create_driver (pluginpath);
- if (driver == null) {
- reporter.simple_error (null, "failed to load driver");
- return null;
- }
+ private static string directory = null;
+ private static string pkg_name = null;
+ private static string gir_name = null;
+ private static string gir_namespace = null;
+ private static string gir_version = null;
+ private static string driverpath = null;
+
+ private static bool add_inherited = false;
+ private static bool _protected = true;
+ private static bool _internal = false;
+ private static bool with_deps = false;
+ private static bool _private = false;
+ private static bool version = false;
+ private static bool use_svg_images = false;
+
+ private static bool disable_diagnostic_colors = false;
+ private static bool verbose = false;
+ private static bool force = false;
+
+ private static string basedir = null;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] defines;
+ private static bool experimental;
+ private static bool experimental_non_null = false;
+ private static string profile;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] import_packages;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] import_directories;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] vapi_directories;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] metadata_directories;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] gir_directories;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] tsources;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] packages;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] alternative_resource_dirs;
+ static string target_glib;
+
+ private const GLib.OptionEntry[] options = {
+ { "directory", 'o', 0, OptionArg.FILENAME, ref directory, "Output directory", "DIRECTORY" },
+
+ { "basedir", 'b', 0, OptionArg.FILENAME, ref basedir, "Base source directory", "DIRECTORY" },
+ { "define", 'D', 0, OptionArg.STRING_ARRAY, ref defines, "Define SYMBOL", "SYMBOL..." },
+ { "profile", 0, 0, OptionArg.STRING, ref profile, "Use the given profile instead of the default", "PROFILE" },
+
+ { "enable-experimental", 0, 0, OptionArg.NONE, ref experimental, "Enable experimental features", null },
+ { "enable-experimental-non-null", 0, 0, OptionArg.NONE, ref experimental_non_null, "Enable experimental enhancements for non-null types", null },
+
+ { "metadatadir", 0, 0, OptionArg.FILENAME_ARRAY, ref metadata_directories, "Look for GIR .metadata files in DIRECTORY", "DIRECTORY..." },
+ { "girdir", 0, 0, OptionArg.FILENAME_ARRAY, ref gir_directories, "Look for .gir files in DIRECTORY", "DIRECTORY..." },
+ { "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, ref vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
+ { "pkg", 0, 0, OptionArg.STRING_ARRAY, ref packages, "Include binding for PACKAGE", "PACKAGE..." },
+
+ { "driver", 0, 0, OptionArg.STRING, ref driverpath, "Name of an driver or path to a custom driver", null },
+
+ { "importdir", 0, 0, OptionArg.FILENAME_ARRAY, ref import_directories, "Look for external documentation in DIRECTORY", "DIRECTORY..." },
+ { "import", 0, 0, OptionArg.STRING_ARRAY, ref import_packages, "Include binding for PACKAGE", "PACKAGE..." },
+ { "alternative-resource-dir", 0, 0, OptionArg.STRING_ARRAY, ref alternative_resource_dirs, "Alternative resource directories", "DIRECTORY..." },
+
+ { "wiki", 0, 0, OptionArg.FILENAME, ref wikidirectory, "Wiki directory", "DIRECTORY" },
+
+ { "deps", 0, 0, OptionArg.NONE, ref with_deps, "Adds packages to the documentation", null },
+
+ { "doclet", 0, 0, OptionArg.STRING, ref docletpath, "Name of an included doclet or path to custom doclet", "PLUGIN"},
+ { "doclet-arg", 'X', 0, OptionArg.STRING_ARRAY, ref pluginargs, "Pass arguments to the doclet", "ARG" },
+
+ { "no-protected", 0, OptionFlags.REVERSE, OptionArg.NONE, ref _protected, "Removes protected elements from documentation", null },
+ { "internal", 0, 0, OptionArg.NONE, ref _internal, "Adds internal elements to documentation", null },
+ { "private", 0, 0, OptionArg.NONE, ref _private, "Adds private elements to documentation", null },
+ { "use-svg-images", 0, 0, OptionArg.NONE, ref use_svg_images, "Generate SVG image charts instead of PNG", null },
+
+ { "package-name", 0, 0, OptionArg.STRING, ref pkg_name, "package name", "NAME" },
+ { "package-version", 0, 0, OptionArg.STRING, ref pkg_version, "package version", "VERSION" },
+ { "gir", 0, 0, OptionArg.STRING, ref gir_name, "GObject-Introspection repository file name", "NAME-VERSION.gir" },
+
+ { "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
+
+ { "force", 0, 0, OptionArg.NONE, ref force, "force", null },
+ { "verbose", 0, 0, OptionArg.NONE, ref verbose, "Show all warnings", null },
+ { "no-color", 0, 0, OptionArg.NONE, ref disable_diagnostic_colors, "Disable colored output", null },
+ { "target-glib", 0, 0, OptionArg.STRING, ref target_glib, "Target version of glib for code generation", "MAJOR.MINOR" },
+ { "", 0, 0, OptionArg.FILENAME_ARRAY, ref tsources, null, "FILE..." },
+
+ { null }
+ };
+
+ private static int quit (ErrorReporter reporter) {
+ if (reporter.errors == 0) {
+ stdout.printf ("Succeeded - %d warning(s)\n", reporter.warnings);
+ return 0;
+ } else {
+ stdout.printf ("Failed: %d error(s), %d warning(s)\n", reporter.errors, reporter.warnings);
+ return 1;
+ }
+ }
+
+ private static bool check_pkg_name () {
+ if (pkg_name == null) {
+ return true;
+ }
+
+ if (pkg_name == "glib-2.0" || pkg_name == "gobject-2.0") {
+ return false;
+ }
+
+ foreach (string package in tsources) {
+ if (pkg_name == package) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private string get_pkg_name () {
+ if (ValaDoc.pkg_name == null) {
+ if (ValaDoc.directory.has_suffix ("/")) {
+ ValaDoc.pkg_name = GLib.Path.get_dirname (ValaDoc.directory);
+ } else {
+ ValaDoc.pkg_name = GLib.Path.get_basename (ValaDoc.directory);
+ }
+ }
+
+ return ValaDoc.pkg_name;
+ }
+
+ private ModuleLoader? create_module_loader (ErrorReporter reporter, out Doclet? doclet, out Driver? driver) {
+ ModuleLoader modules = ModuleLoader.get_instance ();
+
+ doclet = null;
+ driver = null;
+
+ // doclet:
+ string? pluginpath = ModuleLoader.get_doclet_path (docletpath, reporter);
+ if (pluginpath == null) {
+ return null;
+ }
+
+ doclet = modules.create_doclet (pluginpath);
+ if (doclet == null) {
+ reporter.simple_error (null, "failed to load doclet");
+ return null;
+ }
+
+
+ // driver:
- stdout.printf ("Valadoc %s\n", Config.version);
++ driver = new Valadoc.Drivers.Driver ();
+
+ assert (driver != null && doclet != null);
+
+ return modules;
+ }
+
+ private int run (ErrorReporter reporter) {
+ // settings:
+ var settings = new Valadoc.Settings ();
+ reporter.settings = settings;
+
+ settings.pkg_name = this.get_pkg_name ();
+ settings.gir_namespace = ValaDoc.gir_namespace;
+ settings.gir_version = ValaDoc.gir_version;
+ if (ValaDoc.gir_name != null) {
+ settings.gir_name = GLib.Path.get_basename (ValaDoc.gir_name);
+ settings.gir_directory = GLib.Path.get_dirname (ValaDoc.gir_name);
+ if (settings.gir_directory == "") {
+ settings.gir_directory = GLib.Path.get_dirname (ValaDoc.directory);
+ }
+ }
+ settings.pkg_version = ValaDoc.pkg_version;
+ settings.add_inherited = ValaDoc.add_inherited;
+ settings._protected = ValaDoc._protected;
+ settings._internal = ValaDoc._internal;
+ settings.with_deps = ValaDoc.with_deps;
+ settings._private = ValaDoc._private;
+ settings.path = realpath (ValaDoc.directory);
+ settings.verbose = ValaDoc.verbose;
+ settings.wiki_directory = ValaDoc.wikidirectory;
+ settings.pluginargs = ValaDoc.pluginargs;
+
+ settings.experimental = experimental;
+ settings.experimental_non_null = experimental_non_null;
+ settings.basedir = basedir;
+ settings.directory = directory;
+ settings.vapi_directories = vapi_directories;
+ settings.metadata_directories = metadata_directories;
+ settings.gir_directories = gir_directories;
+ settings.target_glib = target_glib;
+ settings.use_svg_images = use_svg_images;
+
+ settings.source_files = tsources;
+ settings.packages = packages;
+
+ settings.profile = profile;
+ settings.defines = defines;
+
+ settings.alternative_resource_dirs = alternative_resource_dirs;
+
+
+ // load plugins:
+ Doclet? doclet = null;
+ Driver? driver = null;
+
+ ModuleLoader? modules = create_module_loader (reporter, out doclet, out driver);
+ if (reporter.errors > 0 || modules == null) {
+ return quit (reporter);
+ }
+
+
+ // Create tree:
+ Valadoc.Api.Tree doctree = driver.build (settings, reporter);
+ if (reporter.errors > 0) {
+ driver = null;
+ doclet = null;
+ return quit (reporter);
+ }
+
+ // register child symbols:
+ Valadoc.Api.ChildSymbolRegistrar registrar = new Valadoc.Api.ChildSymbolRegistrar ();
+ doctree.accept (registrar);
+
+ // process documentation
+ Valadoc.DocumentationParser docparser = new Valadoc.DocumentationParser (settings, reporter, doctree, modules);
+ if (!doctree.create_tree()) {
+ return quit (reporter);
+ }
+
+ DocumentationImporter[] importers = {
+ new ValadocDocumentationImporter (doctree, docparser, modules, settings, reporter),
+ new GirDocumentationImporter (doctree, docparser, modules, settings, reporter)
+ };
+
+ doctree.parse_comments (docparser);
+ if (reporter.errors > 0) {
+ return quit (reporter);
+ }
+
+ doctree.import_comments (importers, import_packages, import_directories);
+ if (reporter.errors > 0) {
+ return quit (reporter);
+ }
+
+ doctree.check_comments (docparser);
+ if (reporter.errors > 0) {
+ return quit (reporter);
+ }
+
+ if (ValaDoc.gir_name != null) {
+ driver.write_gir (settings, reporter);
+ if (reporter.errors > 0) {
+ return quit (reporter);
+ }
+ }
+
+ doclet.process (settings, doctree, reporter);
+ return quit (reporter);
+ }
+
+ static int main (string[] args) {
+ Intl.setlocale (LocaleCategory.ALL, "");
+ ErrorReporter reporter = new ErrorReporter();
+
+ try {
+ var opt_context = new OptionContext ("- Vala Documentation Tool");
+ opt_context.set_help_enabled (true);
+ opt_context.add_main_entries (options, null);
+ opt_context.parse (ref args);
+ } catch (OptionError e) {
+ reporter.simple_error (null, "%s", e.message);
+ stdout.printf ("Run '%s --help' to see a full list of available command line options.\n", args[0]);
+ return quit (reporter);
+ }
+
+ if (disable_diagnostic_colors == false) {
+ unowned string env_colors = Environment.get_variable ("VALA_COLORS");
+ if (env_colors != null) {
+ reporter.set_colors (env_colors);
+ } else {
+ reporter.set_colors (DEFAULT_COLORS);
+ }
+ }
+
+ if (version) {
++ stdout.printf ("Valadoc %s\n", Config.BUILD_VERSION);
+ return 0;
+ }
+
+ if (directory == null) {
+ reporter.simple_error (null, "No output directory specified.");
+ return quit (reporter);
+ }
+
+ if (!check_pkg_name ()) {
+ reporter.simple_error (null, "File already exists");
+ return quit (reporter);
+ }
+
+ if (FileUtils.test (directory, FileTest.EXISTS)) {
+ if (force == true) {
+ bool tmp = remove_directory (directory);
+ if (tmp == false) {
+ reporter.simple_error (null, "Can't remove directory.");
+ return quit (reporter);
+ }
+ } else {
+ reporter.simple_error (null, "File already exists");
+ return quit (reporter);
+ }
+ }
+
+ if (wikidirectory != null) {
+ if (!FileUtils.test(wikidirectory, FileTest.IS_DIR)) {
+ reporter.simple_error (null, "Wiki-directory does not exist.");
+ return quit (reporter);
+ }
+ }
+
+ foreach (unowned string dir in alternative_resource_dirs) {
+ if (!FileUtils.test(dir, FileTest.IS_DIR)) {
+ reporter.simple_error (null, "alternative resource directory '%s' does not exist.".printf (dir));
+ return quit (reporter);
+ }
+ }
+ if (reporter.errors > 0) {
+ return quit (reporter);
+ }
+
+ if (gir_name != null) {
+ long gir_len = gir_name.length;
+ int last_hyphen = gir_name.last_index_of_char ('-');
+
+ if (last_hyphen == -1 || !gir_name.has_suffix (".gir")) {
+ reporter.simple_error (null, "GIR file name '%s' is not well-formed, expected NAME-VERSION.gir", gir_name);
+ return quit (reporter);
+ }
+
+ gir_namespace = gir_name.substring (0, last_hyphen);
+ gir_version = gir_name.substring (last_hyphen + 1, gir_len - last_hyphen - 5);
+ gir_version.canon ("0123456789.", '?');
+
+ if (gir_namespace == "" || gir_version == "" || !gir_version[0].isdigit () || gir_version.contains ("?")) {
+ reporter.simple_error (null, "GIR file name '%s' is not well-formed, expected NAME-VERSION.gir", gir_name);
+ return quit (reporter);
+ }
+
+
+ bool report_warning = true;
+ foreach (string source in tsources) {
+ if (source.has_suffix (".vala") || source.has_suffix (".gs")) {
+ report_warning = false;
+ break;
+ }
+ }
+
+ if (report_warning == true) {
+ reporter.simple_error (null, "No source file specified to be compiled to gir.");
+ return quit (reporter);
+ }
+ }
+
+
+ var valadoc = new ValaDoc( );
+ return valadoc.run (reporter);
+ }
+ }
+
+