Hackers' Guide to Vala

Rodney Lorrimar

Document Author 

Jürg Billeter

Vala Author 

Raffaele Sandrini

Vala Author 

Philip van Hoof

Contribution of the building Vala section. 

Edited by

Rodney Lorrimar

Revision History
Revision 0.1123 Apr 2008
Pre draft

Table of Contents

Environment Issues
Getting the source
Getting this document
Compiling from SVN
Setting up your editor - GNU Emacs
Coding Style
Files
Website, Mailing List, Bug Tracker, IRC
Project Maintainers
License
The Vala Compiler
Vala in a Nutshell
Parser
Attribute Processing
Symbol Resolution
Semantic Analyzer
C Code Generation
C Code Compilation and Linking
Vala Bindings - VAPI
CCode Attribute Reference
libgee Internal
Other Tools
vapigen
gen-project
vala-gen-introspect
Testing
Documentation
Build System
Out-of-tree build
Directory Index
Index
GNU Free Documentation License

The goal of this document is to provide a single point of information for developers interested in improving Vala.

It is hoped that that this document will encourage more Vala users to contribute to Vala by finding/fixing bugs, writing documentation, writing test-cases, and implementing new features.

In the opinion of this document's author, a quality Vala 1.0 is an important part of the future of the GNOME Platform, because it will simplify the task of creating and maintaining excellent language-neutral libraries, which are necessary for the next generation of applications.

The Vala code is fresh, and easy to read. The variable and class names are descriptive, and one often has a general feel of what the code is supposed to do, so the sparse comments are generally not a problem. However, because it is a compiler, Vala is inevitably long, and its call stack deep. This document should provide a high-level view of how Vala is put together.

Eventually, most of this document will be merged into the source code and generated from there. However the necessary tool has not been written yet.

Environment Issues

Getting the source

The Vala source code is available from GNOME svn.

http://svn.gnome.org/svn/vala/trunk

Git

Git allows developers without SVN access to maintain their own branches and simplifies the task of submitting patches back to the project maintainers.

It allows all users to participate in development on more equal terms with the developers who have SVN access.

Follow these instructions to get your own git tree from the svn.

Getting this document

For the time being, until this document is of suitable quality to be released, it will live in a separate git tree. Anyone interested can make edits on the mob branch.

git pull git://repo.or.cz/vala-hackers-guide.git

Compiling from SVN

Prerequisites

Install packages like a C compiler, glib-2.0. Older versions (0.20 and older) require flex and bison. TODO: complete this list

Step One

Grab yourself a vala to c compiled release of vala. Vala is self-hosting so it needs another vala compiler to compile itself. Since vala compiles to C code, you can use a tarball release of vala to compile the generated C code of such a release into a working Vala compiler, that will compile the Vala compiler which you might have checked out from the repository.

http://live.gnome.org/Vala/Release

Table 1. Required release versions

SVN VersionRelease required to build
1207 and later0.20
xxxx0.17

Step Two

Compiling the release which you just grabbed:

tar jxvf vala-x.y.z.tar.bz2
cd vala-x.y.z
./configure --prefix=/opt/vala-release
make && sudo make install
    

Step Three

Compiling the newest Vala from the repository: Fixme: anon SVN

svn co svn co svn+ssh://[user]@svn.gnome.org/svn/vala/trunk vala
cd vala
export VALAC=/opt/vala-release/bin/vala
./autogen.sh --prefix=/opt/vala
make && sudo make install
    

Maybe you want to compile the new Vala with itself. Then you simply go over it again:

make distclean
export VALAC=/opt/vala/bin/vala
./autogen.sh --prefix=/opt/vala
make && sudo make install
    

Out-of-tree builds

The build works, but *.[ch] files are left behind in the source directory.

Setting up your editor - GNU Emacs

The csharp-mode available from fixme does a good-enough job of syntax highlighting.

"Intellisense" using the csharp Semantic Wisent parser partially works.

This document's author intends to extend csharp-mode to support Vala and to create a new Semantic parser for Vala, though no significant work has been done yet.

Here is something you can put in .emacs which will make editing Vala in emacs easier.

;; C# mode (used for vala!)
(require 'csharp-mode)

(defcustom vala-mode-hook nil
  "*Hook called by `vala-mode'."
  :type 'hook
  :group 'c)

;; Vala
(defun vala-mode ()
  "Vala hack."
  (interactive)
;  (kill-all-local-variables)
;  (c-initialize-cc-mode t)
  (csharp-mode)
  (setq mode-name "Vala")
  (run-hooks 'c-mode-common-hook)
  (c-set-style "linux")
  (setq indent-tabs-mode t)
  (setq c-basic-offset 4)
  (setq tab-width 4)
; auto stuff isn't good yet
  (c-toggle-auto-newline -1)
  (c-toggle-hungry-state -1)
  (run-hooks 'vala-mode-hook))

(add-to-list 'auto-mode-alist '("\\.vala\\'" . vala-mode))

;; If you have CEDET or Semantic loaded, uncomment this line
;(semantic-load-enable-code-helpers)
  

Coding Style

The coding style used in Vala itself seems to be a variation of the GTK+ coding style.

  • Tabs rather than spaces.

  • Tab width unspecified, but 4 works well.

  • Hanging braces.

  • Cuddled else.

  • Braces not necessary for single-line blocks.

  • Variable and method identifiers in lowercase, words seperated by underscores.

  • Type identifiers in CamelCase.

  • Enum members and constants in ALL_CAPS, words seperated by underscores.

  • C-style /* comments. */

  • Hungarian notation not used.

  • Variables often declared without type (i.e. "var").

  • No line-length limit.

  • No function-length limit.

  • Space between method name and parameters' opening parenthesis.

  • Property "get", "set", "default" declaration all on one line, seperated by semicolons, if default implementations are used.

  • If properties have implementations, then "get {", "set {" open new lines.

  • Attributes on their own line.

  • JavaDoc-style commenting on types, methods, variables.

  • Header at top of file contains:

            /* filename.vala
             *
             * Copyright (C) 20yy-20yy  Copyright Holder <email@address>
             *
             * License text.
    	 * 
             * Author:
             * 	Programmer Name <programmer@email>
             */
        

Files

Vala source files are named in the GTK+ style, i.e. all lowercase, which no separators between words, in the format namespaceclassname.vala. For example, the filename for Vala.FormalParameter is valaformalparameter.vala.

Classes can be split across files, and this is often done for classes with a lot of methods, or very long methods.

For the Vala compiler and library there is only one namespace, and it is called "Vala". Don't put "using Vala;"; instead qualify the name of types you declare. For example "class Vala.FormalParameter : Symbol".

Website, Mailing List, Bug Tracker, IRC

  • http://www.valaproject.org

  • GNOME Bugzilla - http://bugs.gnome.org

  • #vala on GIMPnet

Project Maintainers

The principle authors and project maintainers are Jürg Billeter and Raffaele Sandrini.

License

Vala compiler is licensed under LGPL 2.1, so that proprietary programs compiled with Vala can be distributed under different licenses and possibly without source code.

The Vala Compiler

I suppose the best place to start is valac, the tool which Vala programmers know the best.

Vala in a Nutshell

The Vala compiler valac is a small shell around libvala which handles command-line arguments, locates the sources and libraries which are required, and drives the compilation procedure.

Figure 1. How valac is linked

How valac is linked

All the important work such as parsing, error checking/reporting, code generation, calling gcc, is done in libvala.

The code for valac can be found in compiler/valacompiler.vala.

Command-line Options

These are handled in the normal way by the Vala binding to GLib.OptionContext. Most of the instance variables in Vala.Compiler are referenced in the options array. It's not very interesting.

The Compilation Procedure and Vala.CodeContext

Vala.Compiler plugs together the classes of libvala in a big pipeline. This modular design means that different Vala tools can share their code. Most modules have impressive-sounding names like AlgorithmicFrobnicator.

Procedure 1. valac Pipeline

  1. Initialize context with command-line options.

  2. Plug in a code generator.

  3. Add packages from command-line and the non-optional GLib.

  4. Add sources, Vala, VAPI, and C from command-line.

  5. Parse everything.

  6. Process attributes.

  7. Resolve symbols.

  8. Setup a DBus Binding Provider.

  9. Setup the Semantic Analyzer.

  10. Plug in the DBus Binding Provider to the Semantic Analyzer.

  11. Do the Semantic Analysis

  12. Build Config.

  13. Check that null variables are treated properly.

  14. Analyse code with the memory manager. ???

  15. Use the code generator to emit code.

  16. Write out VAPI and GIDL files, if a library is being compiled.

  17. Compile the generated C code.

The individual steps will be explained later, but first Vala.CodeContext, the data structure which holds everything together. It stores the compile options which were specified on the command line, and a list of source files to compile. There is only one CodeContext instantiated and its reference is passed around a lot, so effectively it's a global variable.

Vala.CodeContext is the root of the code tree, because it contains the root Namespace, which holds references to all parsed code nodes. In addition to the code tree, the context contains a reference to a code generator object. This object walks the code tree and generates code.

Vala.CodeContext contains an important method called accept, which initiates a depth-first traversal of the code tree. This method, and the CodeVisitor pattern will be discussed later.

ignore_node method contains the logic for the "Conditional" attribute.

For every one of the 77 (or so) code node types, there is a create_code_node_type method which constructs the code node and links it with the code generator. The parser will use these methods to create code nodes as it parses them, which know how to emit code later.

Figure 2. Data diagram

Data diagram

The Vala code tree is an abstract syntax tree (AST) built by parsing the Vala sources. For example, if you see a class called Vala.Destructor which inherits Vala.Symbol, then it is a part of the AST. Data structures for the AST and the parser which builds it are in the vala directory.

Vala also uses a tree to represent the C code that will be output. Data structures for the C code tree are in the ccode directory.

The machinery which transforms the Vala AST into a C code tree is in the gobject directory. The reason it's there is because Vala outputs "GObject C" rather than plain C. GObject C is arranged in a particular object-oriented way, uses reference counted memory management, signals, data-structures, and links with glib.

Vala is split upon these lines, most probably to break the system into conceptually-related, understandable chunks. However, with suitable modifications, the different modules could be replaced. Conceivably, Vala could produce non-GObject C code. More realistically, Vala could produce intermediate code as a GCC frontend.

Parser

The parser reads Vala and VAPI code and outputs an AST. In the eyes of the parser, Vala and VAPI are the same thing. The difference to us is that VAPI files never have method definitions, but the parser will read pretty much everything as long as it seems syntactically correct. Most errors are caught later by the Semantic Analyzer.

Before 0.3.1, Vala's parser was the classic flex scanner and Bison LALR parser combination. But as of SVN 1194, the parser is a hand-crafted recursive descent parser. The parser is in vala/valaparser.vala and its lexer is in vala/valascanner.vala.

The entry point of the parser is Vala.Parser.parse(). This method is called by Vala.Compiler.run(). Vala.Parser is an implementation of Vala.CodeVisitor for source files.

Visitors and Ping Pong

CodeVisitor is an abstract base class which provides 75 empty virtual methods for each kind of code node. A class which inherits CodeVisitor is supposed to do some kind of processing of the code tree. Here are all the CodeVisitor classes in Vala:

     public class Vala.CodeVisitor : Object
       public class Vala.AttributeProcessor : CodeVisitor
       public class Vala.CFGBuilder : CodeVisitor
       public class Vala.CodeGenerator : CodeVisitor
       public class Vala.GIdlParser : CodeVisitor
       public class Vala.GIdlWriter : CodeVisitor
       public class Vala.InterfaceWriter : CodeVisitor
       public class Vala.MemoryManager : CodeVisitor
       public class Vala.NullChecker : CodeVisitor
       public class Vala.Parser : CodeVisitor
       public class Vala.SemanticAnalyzer : CodeVisitor
       public class Vala.SymbolResolver : CodeVisitor

CodeVisitor works closely with the different Vala.CodeNode classes to traverse the code tree. Here are all the code node types in Vala:

public abstract class Vala.CodeNode : Object
  public interface Vala.Statement : CodeNode
  public class Vala.BreakStatement : CodeNode, Statement
  public class Vala.ContinueStatement : CodeNode, Statement
  public class Vala.DeclarationStatement : CodeNode, Statement
  public class Vala.DeleteStatement : CodeNode, Statement
  public class Vala.DoStatement : CodeNode, Statement
  public class Vala.EmptyStatement : CodeNode, Statement
  public class Vala.ExpressionStatement : CodeNode, Statement
  public class Vala.ForStatement : CodeNode, Statement
  public class Vala.IfStatement : CodeNode, Statement
  public class Vala.LockStatement : CodeNode, Statement
  public class Vala.ReturnStatement : CodeNode, Statement
  public class Vala.SwitchStatement : CodeNode, Statement
  public class Vala.ThrowStatement : CodeNode, Statement
  public class Vala.TryStatement : CodeNode, Statement
  public class Vala.WhileStatement : CodeNode, Statement

  public abstract class Vala.DataType : CodeNode
    public abstract class Vala.ReferenceType : DataType
      public class Vala.ArrayType : ReferenceType
      public class Vala.ClassType : ReferenceType
      public class Vala.ErrorType : ReferenceType
      public class Vala.InterfaceType : ReferenceType
      public class Vala.NullType : ReferenceType

    public class Vala.DelegateType : DataType
    public class Vala.InvalidType : DataType
    public class Vala.MethodType : DataType
    public class Vala.PointerType : DataType
    public class Vala.SignalType : DataType
    public class Vala.TypeParameterType : DataType
    public class Vala.UnresolvedType : DataType
    public class Vala.ValueType : DataType
    public class Vala.VoidType : DataType

  public abstract class Vala.Symbol : CodeNode
    public abstract class Vala.Typesymbol : Symbol

    public class Vala.Block : Symbol, Statement
    public class Vala.Constructor : Symbol
    public class Vala.Destructor : Symbol
    public class Vala.EnumValue : Symbol
    public class Vala.ErrorCode : Symbol
    public class Vala.FormalParameter : Symbol
    public class Vala.Member : Symbol
    public class Vala.Namespace : Symbol
    public class Vala.TypeParameter : Symbol
    public class Vala.VariableDeclarator : Symbol

  public abstract class Vala.Expression : CodeNode
    public abstract class Vala.Literal : Expression
      public class Vala.BooleanLiteral : Literal
      public class Vala.CharacterLiteral : Literal
      public class Vala.IntegerLiteral : Literal
      public class Vala.NullLiteral : Literal
      public class Vala.RealLiteral : Literal
      public class Vala.StringLiteral : Literal

    public class Vala.AddressofExpression : Expression
    public class Vala.ArrayCreationExpression : Expression
    public class Vala.Assignment : Expression
    public class Vala.BaseAccess : Expression
    public class Vala.BinaryExpression : Expression
    public class Vala.CastExpression : Expression
    public class Vala.ConditionalExpression : Expression
    public class Vala.ElementAccess : Expression
    public class Vala.InitializerList : Expression
    public class Vala.InvocationExpression : Expression
    public class Vala.LambdaExpression : Expression
    public class Vala.MemberAccess : Expression
    public class Vala.ObjectCreationExpression : Expression
    public class Vala.ParenthesizedExpression : Expression
    public class Vala.PointerIndirection : Expression
    public class Vala.PostfixExpression : Expression
    public class Vala.ReferenceTransferExpression : Expression
    public class Vala.SizeofExpression : Expression
    public class Vala.Tuple : Expression
    public class Vala.TypeCheck : Expression
    public class Vala.TypeofExpression : Expression
    public class Vala.UnaryExpression : Expression

  public class Vala.LocalVariableDeclaration : CodeNode
  public class Vala.CatchClause : CodeNode
  public class Vala.Attribute : CodeNode
  public class Vala.PropertyAccessor : CodeNode
  public class Vala.MemberInitializer : CodeNode
  public class Vala.SwitchLabel : CodeNode
  public class Vala.UnresolvedSymbol : CodeNode
  public class Vala.NamedArgument : CodeNode
  public class Vala.NamespaceReference : CodeNode

All CodeNodes except the root have a non-null parent CodeNode. Some specializations of CodeNode may have children. The type and number of children are declared in the specialized class.

The two important methods in a CodeNode are accept and accept_children. accept() lets the node declare to the CodeVisitor what it is, so the CodeVisitor can act on it. For example, Vala.Struct.accept()

         public override void accept (CodeVisitor visitor) {
             visitor.visit_struct (this);  /* I am a struct! */
         }

accept_children() lets the node accept all of its children so they can declare themselves to the CodeVisitor. This is the recursive part of the traversal. For example, a Struct code node has a list of base types, type parameters, fields, constants, and methods. Vala.Struct.accept_children() accepts all of these.

     public override void accept_children (CodeVisitor visitor) {
         foreach (DataType type in base_types) {
             type.accept (visitor);
         }

         foreach (TypeParameter p in type_parameters) {
             p.accept (visitor);
         }

         foreach (Field f in fields) {
             f.accept (visitor);
         }

         foreach (Constant c in constants) {
             c.accept (visitor);
         }

         foreach (Method m in methods) {
             m.accept (visitor);
         }
     }

As you can see, the CodeVisitor is repeatedly asked to visit different code nodes. It can do whatever analysis is necessary and then traverse deeper into the code tree. This is what a hypothetical implementation of XmlGenerator.visit_struct() might look like:

     public override void visit_struct (Struct st) {
         /* Do some processing of this struct. */
         stdout.printf ("<vala:struct name=\"%s\">\n", st.name);

         /* recurse through struct's children */
         st.accept_children (this);

         /* Do some more processing of the struct, now that its
          * children have been accepted. */
         stdout.printf ("</vala:struct>\n");
     }

The visit_ methods of a CodeVisitor needn't call CodeNode.accept_children(), if it isn't necessary to traverse the whole depth of the code tree. It also isn't necessary to write visit_ methods for every kind of code node, because empty implementations are already provided in CodeVisitor.

What does this have to do with ping pong? Well, the flow of control bounces between the CodeVisitor and the CodeNodes: accept, visit, accept, visit, ... When you navigate the code you will probably find yourself bouncing between different classes.

Back to the Parser

Vala.Parser is a highly specialized CodeVisitor - the only type of code node it visits is a Vala.SourceFile. However the Parser calls back to the context and uses it to create code nodes (mentioned before), then adds these code nodes into the context's root code node.

Error Handling

I don't want to spoil your fun too much by going into the details of the parser, other than that every parse_ function can throw a ParseError. ParseError is caught when parsing a block or the declarations of a namespace, class, struct, or interface. Fixme.

Grammar of Vala

This grammar is hand-generated from Vala.Parser. Sometimes the structure of this grammar diverges slightly from the code, for example optional non-terminal symbols. However the non-terminal symbol names usually match a parse_ method in Vala.Parser.

input ::=
        using_directive* root_declarations

using_directive ::=
        "using" symbol ("," symbol)* ";"

// from parse_symbol_name
symbol_name ::=
        identifier ("." identifier)*

// from parse_identifier, skip_identifier, get_last_string
identifier ::=
        TOKEN

// corresponds to parse_declarations
root_declarations ::=
        namespace_declarations

// corresponds to parse_declarations
other_declarations ::=
        namespace_declarations
           | class_declarations
           | struct_declarations
           | interface_declarations

// corresponds to parse_declarations
declarations ::=
        "{" other_declarations "}"

namespace_declarations ::=
        namespace_member*

// from parse_namespace_member
namespace_member ::=
        namespace_declaration
           | class_declaration
           | interface_declaration
           | struct_declaration
           | enum_declaration
           | error_domain_declaration // ???
           | delegate_declaration
           | method_declaration
           | field_declaration
           | constant_declaration

// from parse_class_member
class_member ::=
         class_declaration
           | struct_declaration
           | enum_declaration
           | delegate_declaration
           | method_declaration
           | signal_declaration
           | field_declaration
           | constant_declaration
           | property_declaration
           | constructor_declaration
           | destructor_declaration

// from parse_declaration and parse_namespace_declaration
namespace_declaration ::=
        attribute* "namespace" symbol_name declarations

// from parse_declaration and parse_class_declaration
class_declaration ::=
        [access_modifier] type_declaration_modifiers
        "class" symbol_name [type_parameter_list] ":" type ("," type)*
        declarations

// from parse_access_modifier
access_modifier ::=
        "private"
	   | "protected"
	   | "public"

// from parse_type_declaration_modifiers
type_declaration_modifiers ::=
        ("abstract" | "static")*

// from parse_member_declaration_modifiers
member_declaration_modifiers ::=
        ("abstract" | "class" | "inline" | "override" | "static" | "virtual")*

// from parse_type_parameter_list
type_parameter_list ::=
        "<" identifier ("," identifier)* ">"

// fixme: complete the grammar, check it

Attribute Processing

Vala.Attributes are code tree nodes and have a name and a possibly empty list of key-value arguments. Some types of code tree nodes have as children a list of Attributes. The attribute processor's purpose is to interpret the attributes which were parsed into the code tree.

Later in the compilation, the results of attribute processing will be used, for example the CCode cname attribute affects what function names are used in emitted C code.

All attributes except for Conditional are handled from Vala.AttributeProcessor. I don't know where and how conditional is handled, but there is a function ignore_node() in Vala.CodeContext.

Vala.AttributeProcessor is a CodeVisitor which simply calls the process_attributes() method on every namespace, class, struct, interface, enum, method, constructor, parameter, property, delegate, constant, field, and signal that it visits.

Inside the process_attributes() method of each of these objects, a series of string comparisons will be made to parse the attributes. If the attribute is called "CCode", then the process_ccode_attributes() function will be called to parse the key-value pairs supplied.

fixme: mention Vala.Parser.set_attributes()

Attributes Recognized by Vala

Vala.Namespace
  • CCode

Vala.Class
  • CCode

  • ErrorBase

Vala.Struct
  • CCode

  • SimpleType

  • IntegerType

  • FloatingType

Vala.Interface
  • CCode

  • DBusInterface

    • DBusGProxy

Vala.Enum
  • CCode

  • Flags

Vala.Method
  • CCode

  • ReturnsModifiedPointer

  • FloatingReference

  • NoArrayLength

  • PrintfFormat

  • Import

Vala.CreationMethod

Same as Vala.Method - this class inherits Method

Vala.FormalParameter
  • CCode

Vala.Property
  • Notify

  • NoAccessorMethod

  • Description

    • nick

    • blurb

Vala.Delegate
  • CCode

  • NoArrayLength

Vala.Constant
  • CCode

Vala.Field
  • CCode

  • NoArrayLength

Vala.Signal
  • HasEmitter

Symbol Resolution

Vala.SymbolResolver is a CodeVisitor that exchanges Vala.UnresolvedTypes in the parse tree with Vala.DataTypes and links Vala.NamespaceReferences with the correct namespace symbol. Additionally, it checks base types for classes so that classes don't inherit from multiple classes or themselves, and likewise it checks that interfaces don't need to implement themselves.

Data Types

Every expression has a static type. This is computed by the semantic analyser. Vala.DataType is called a "type reference" because it contains a reference to a Vala.Typesymbol (a class, interface, etc) as well as information about the expression's type e.g. if it can be null, if it's an out parameter.

Fixme: expand this section

Symbols

A Vala.Symbol is a specialization of Vala.CodeNode. All symbols except for the root symbol are contained within another's scope. Types have scope and variables have scope. For types and variables, scope determines their accessibility, subject to access modifiers. For variables, scope also determines their lifetime. As the code tree is traversed, SymbolResolver keeps track of the current scope. For example, when a class is visited, current_scope is set to that class's scope.

When the parser parses a type, e.g. in the statement Gtk.Window main_window;, the type Gtk.Window is initially a Vala.UnresolvedType. In visit_data_type(), the UnresolvedType code node asks its parent to replace it with a new Vala.DataType created with resolve_type().

UnresolvedTypes have UnresolvedSymbols. resolve_type() uses resolve_symbol() to find the Typesymbol referred to, and then wraps it in a new DataType object.

resolve_symbol is a recursive method which looks up an unresolved symbol's name in the current scope and returns the corresponding Typesymbol. The base case is when the UnresolvedSymbol has no qualifiers, e.g. Window. The recursive case is when the symbol looks like Gtk.Window or Gtk.Orientation.HORIZONTAL. In Vala.Parser.parse_symbol_name(), the symbol is built inside-out, so Gtk.Orientation.HORIZONTAL is parsed as

UnresolvedSymbol
    (UnresolvedSymbol
        (UnresolvedSymbol(null, "Gtk"),
         "Orientation"),
     "HORIZONTAL")

This is inside-out because Orientation is the parent scope of HORIZONTAL, but Orientation is the child node of HORIZONTAL.

In the base case, the symbol's name is looked up in current_scope. If the symbol is not found there, then the scope of all imported namespaces is searched. If more than one imported namespace contains the symbol, an "ambiguous reference" error will be reported.

In the recursive case, resolve_symbol() is called on the child node to give a parent scope, in which the symbol is looked up.

One last function of SymbolResolver is in visit_variable_declarator() - to mark a variable type reference as "nullable" if the variable's type is a class, interface, array or error (reference type). This is used later by Vala.NullChecker.

Semantic Analyzer

C Code Generation

C Code Compilation and Linking

Vala Bindings - VAPI

The bindings are located in the vapi directories.

CCode Attribute Reference

CCode attributes influence the C code which is generated by Vala. They have the form

    [CCode (argument0 = value0, argument1 = value1, ...)]
  

Usually these attributes are not required because Vala chooses normal values. However, they exist for the cases when Vala's chosen values don't fit the API.

Warning

I'm not sure how much of this will apply once we have GObject introspection.

Table 2. CCode Attributes

NameApplies toTypeExample
Description
array_length_posconstructor, delegate, method, parameterstring 
array_length_pos
cheader_filenameclass, constant, constructor, delegate, enum, field, interface, method, namespace, structstring - comma-separated list of headers"glib.h"
The header file(s) which should be #included in the emitted C code, so that this symbol is usable. If more than one header file is needed, separate them by commas.
cnameclass, constant, constructor, delegate, enum, field, method, structstring"gboolean"
The name that this symbol will take when translated into C code. If this attribute is not specified, the symbol will get a name with the normal vala translation rules.
const_cnameclass, structstring 
const_cname
copy_function classstring 
copy_function
cprefixclass, enum, namespace, structstring 
cprefix
default_valuestructstring - C value expression"FALSE"
A C expression representing this type's default value. This is needed because ...
delegate_target_posconstructor, delegate, method, parameterstring 
delegate_target_pos
free_functionclassstring 
free_function
get_value_functionclass, structstring - function name"g_value_get_boolean"
  type_cnameget_value_function (const GValue *value);
	  
A function which will return an object when passed a GValue. This is used ...
has_type_idclass, enumstring 
has_type_id
instance_posconstructor, delegate, methodstring 
instance_pos
lower_case_cprefixclass, enum, interface, namespacestring 
lower_case_cprefix
marshaller_type_nameclass, structstring"BOOLEAN"
Don't know yet.
ref_functionclassstring 
ref_function
sentinelconstructor, methodstring 
sentinel
set_value_functionclass, structstring - function name"g_value_set_boolean"
  void set_value_function (GValue *value, type_cname v);
	  
A function that will set a GValue with an object of this type. This is used ...
skipparameterstring 
skip
type_cnameinterfacestring 
type_cname
type_idclass, enum, structstring - "G_TYPE_BOOLEAN"
The GObject type system type that this object is registered with. If type_id is not specified, Vala uses a type ID based on the type's name.
unref_functionclassstring 
unref_function
vfunc_nameconstructor, methodstring 
vfunc_name

libgee Internal

What is the difference between external and internal libgee?

Other Tools

vapigen

gen-project

vala-gen-introspect

Testing

A goal for Vala 1.0 is to have every tests for every documented feature of the language.

Documentation

XML sources for the Vala Reference are in the doc/vala directory. You can rebuild the docs by cd'ing into doc/vala and typing make. Currently the conversion to HTML is done using xsltproc and a simple stylesheet.

Docbook XML sources for the Hackers' Guide are in doc/hackers. HTML documentation is built by default. This document can be rebuilt by running make in doc/hackers.

Generated binding documentation - fixme.

libvala documentation - fixme.

http://live.gnome.org/Vala - The Wiki is open to anyone who would like to make a quality contribution.

Build System

Vala is built using the standard GNU Autotools. The built executables are actually stored in .libs directories and wrapped by scripts. Therefore to debug, follow these instructions fixme.

./configure uses the AC_PATH_PROG macro to choose the valac which is on your path, or one specified in the VALAC environment variable. Therefore, to build Vala with your own valac, type this, for example:

    VALAC=$HOME/dev/vala-0.20/compiler/valac ./configure --prefix=$HOME/prefix
  

Out-of-tree build

An out-of-tree build does not properly work yet. Out-of-tree builds have the advantage that your source tree is not cluttered with built files. Suppose you have vala checked out in ~/dev/valatrunk.

    rodney@solaria:~/dev % svn co http://svn.gnome.org/svn/vala/trunk valatrunk
    rodney@solaria:~/dev % ls valatrunk
fixme           fixme          fixme                  fixme           
aclocal.m4      config.log     gobject-introspection  README
AUTHORS         config.status  INSTALL                stamp-h1
autogen.sh      config.sub     install-sh             tests
autom4te.cache  configure      libtool                vala
ccode           configure.ac   ltmain.sh              vala-1.0.pc
ChangeLog       COPYING        MAINTAINERS            vala-1.0.pc.in
compile         depcomp        Makefile               vapi
compiler        doc            Makefile.am            vapigen
config.guess    gee            Makefile.in            ylwrap
config.h        gen-project    missing
config.h.in     gobject        NEWS
fixme           fixme          fixme                  fixme           
    rodney@solaria:~/dev % mkdir buildvala
    rodney@solaria:~/dev % cd buildvala
    rodney@solaria:~/dev/buildvala % ../valatrunk/autogen.sh --prefix=$HOME/dev/prefix
    rodney@solaria:~/dev/buildvala % make

All Makefiles, etc, generated by configure will be put in the buildvala directory and you can run make directly from there.

Directory Index

Index

Should automatically generate this from Docbook.

GNU Free Documentation License

etc.