Commit 49177f7d authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

merge SimpleName into MemberAccess adapt to change in Class support

2006-07-06  Jürg Billeter  <j@bitron.ch>

	* vala/parser.y, vala/valacodevisitor.vala, vala/valasymbolbuilder.vala,
	  vala/valasemanticanalyzer.vala, vala/valamemorymanager.vala,
	  vala/valacodegenerator.vala, vala/valatypereference.vala, vala/vala.h,
	  vala/Makefile.am: merge SimpleName into MemberAccess
	* vala/valasymbolresolver.vala, vala/valainterfacewriter.vala: adapt to
	  change in Class
	* vala/valasemanticanalyzer.vala: support non-static lambda expressions
	  and lambda expressions without return values
	* vala/valacodegenerator.vala: support conditional expressions, support
	  lambda expressions as signal handlers, support read-only and
	  write-only properties
	* vala/valacodevisitor.vala, vala/valamemorymanager.vala,
	  vala/valaassignment.vala: visit at beginning and end
	* vala/valacallback.vala: add instance property
	* vala/valasignal.vala: add get_callback method
	* vala/valacastexpression.vala, vala/valacharacterliteral.vala,
	  vala/valaclass.vala, vala/valamemberaccess.vala, vala/valasignal.vala:
	  add interface documentation, use implicit namespace specification

svn path=/trunk/; revision=66
parent bf6a3316
2006-07-06 Jürg Billeter <j@bitron.ch>
* vala/parser.y, vala/valacodevisitor.vala, vala/valasymbolbuilder.vala,
vala/valasemanticanalyzer.vala, vala/valamemorymanager.vala,
vala/valacodegenerator.vala, vala/valatypereference.vala, vala/vala.h,
vala/Makefile.am: merge SimpleName into MemberAccess
* vala/valasymbolresolver.vala, vala/valainterfacewriter.vala: adapt to
change in Class
* vala/valasemanticanalyzer.vala: support non-static lambda expressions
and lambda expressions without return values
* vala/valacodegenerator.vala: support conditional expressions, support
lambda expressions as signal handlers, support read-only and
write-only properties
* vala/valacodevisitor.vala, vala/valamemorymanager.vala,
vala/valaassignment.vala: visit at beginning and end
* vala/valacallback.vala: add instance property
* vala/valasignal.vala: add get_callback method
* vala/valacastexpression.vala, vala/valacharacterliteral.vala,
vala/valaclass.vala, vala/valamemberaccess.vala, vala/valasignal.vala:
add interface documentation, use implicit namespace specification
2006-07-05 Jürg Billeter <j@bitron.ch>
* vala/parser.y: don't pass parameter list to lambda expression
......
......@@ -212,9 +212,6 @@ libvala_la_SOURCES = \
valasignal.c \
valasignal.h \
valasignal.vala \
valasimplename.c \
valasimplename.h \
valasimplename.vala \
valasourcefile.c \
valasourcefile.h \
valasourcefile.vala \
......
......@@ -511,7 +511,7 @@ simple_name
: IDENTIFIER
{
ValaSourceReference *src = src(@1);
$$ = VALA_EXPRESSION (vala_simple_name_new ($1, src));
$$ = VALA_EXPRESSION (vala_member_access_new (NULL, $1, src));
g_free ($1);
g_object_unref (src);
}
......
......@@ -48,7 +48,6 @@
#include <vala/valapropertyaccessor.h>
#include <vala/valareturnstatement.h>
#include <vala/valasignal.h>
#include <vala/valasimplename.h>
#include <vala/valasourcefile.h>
#include <vala/valasourcereference.h>
#include <vala/valastringliteral.h>
......
......@@ -58,9 +58,12 @@ public class Vala.Assignment : Expression {
public override void accept (CodeVisitor! visitor) {
left.accept (visitor);
visitor.visit_begin_assignment (this);
right.accept (visitor);
visitor.visit_assignment (this);
visitor.visit_end_assignment (this);
}
}
......
......@@ -31,6 +31,13 @@ public class Vala.Callback : DataType {
*/
public TypeReference return_type { get; set; }
/**
* Specifies whether callback supports calling instance methods.
* The reference to the object instance will be appended to the end of
* the argument list in the generated C code.
*/
public bool instance { get; set; }
private List<FormalParameter> parameters;
private string cname;
......
......@@ -22,20 +22,35 @@
using GLib;
namespace Vala {
public class CastExpression : Expression {
public Expression inner { get; construct; }
public TypeReference type_reference { get; construct; }
/**
* Represents a type cast in the source code.
*/
public class Vala.CastExpression : Expression {
/**
* The expression to be casted.
*/
public Expression! inner { get; set construct; }
/**
* The target type.
*/
public TypeReference! type_reference { get; set construct; }
public static ref CastExpression new (Expression inner, TypeReference type, SourceReference source) {
return (new CastExpression (inner = inner, type_reference = type, source_reference = source));
}
public override void accept (CodeVisitor visitor) {
inner.accept (visitor);
type_reference.accept (visitor);
/**
* Creates a new cast expression.
*
* @param inner expression to be casted
* @param type target type
* @return newly created cast expression
*/
public static ref CastExpression! new (Expression! inner, TypeReference! type, SourceReference source) {
return (new CastExpression (inner = inner, type_reference = type, source_reference = source));
}
public override void accept (CodeVisitor visitor) {
inner.accept (visitor);
type_reference.accept (visitor);
visitor.visit_cast_expression (this);
}
visitor.visit_cast_expression (this);
}
}
......@@ -22,16 +22,27 @@
using GLib;
namespace Vala {
public class CharacterLiteral : Literal {
public string value { get; set; }
/**
* Represents a single literal character.
*/
public class Vala.CharacterLiteral : Literal {
/**
* The literal value.
*/
public string! value { get; set construct; }
public static ref CharacterLiteral! new (string c, SourceReference source) {
return (new CharacterLiteral (value = c, source_reference = source));
}
public override void accept (CodeVisitor! visitor) {
visitor.visit_character_literal (this);
}
/**
* Creates a new character literal.
*
* @param c character
* @param source reference to source code
* @return newly created character literal
*/
public static ref CharacterLiteral! new (string! c, SourceReference source) {
return (new CharacterLiteral (value = c, source_reference = source));
}
public override void accept (CodeVisitor! visitor) {
visitor.visit_character_literal (this);
}
}
......@@ -22,207 +22,330 @@
using GLib;
namespace Vala {
public class Class : DataType {
List<string> type_parameters;
public List<TypeReference> base_types;
public Class base_class;
public bool is_abstract;
List<Constant> constants;
List<Field> fields;
List<Method> methods;
List<Property> properties;
List<Signal> signals;
public Constructor constructor { get; set; }
public Destructor destructor { get; set; }
public string cname;
public string lower_case_csuffix;
public bool has_private_fields;
public static ref Class new (string! name, SourceReference source) {
return (new Class (name = name, source_reference = source));
/**
* Represents a class declaration in the source code.
*/
public class Vala.Class : DataType {
/**
* Specifies the base class.
*/
public Class base_class { get; set; }
/**
* Specifies whether this class is abstract. Abstract classes may not be
* instantiated.
*/
public bool is_abstract { get; set; }
/**
* Specifies whether this class has private fields.
*/
public bool has_private_fields {
get {
return _has_private_fields;
}
public void add_base_type (TypeReference! type) {
base_types.append (type);
set {
/* FIXME: dummy accessor due to vala compiler bug */
}
}
private string cname;
private string lower_case_csuffix;
private bool _has_private_fields;
List<string> type_parameters;
private List<TypeReference> base_types;
List<Constant> constants;
List<Field> fields;
List<Method> methods;
List<Property> properties;
List<Signal> signals;
/**
* Specifies the instance constructor.
*/
public Constructor constructor { get; set; }
/**
* Specifies the instance destructor.
*/
public Destructor destructor { get; set; }
/**
* Creates a new class.
*
* @param name type name
* @param source reference to source code
* @return newly created class
*/
public static ref Class! new (string! name, SourceReference source) {
return (new Class (name = name, source_reference = source));
}
public void add_type_parameter (TypeParameter! p) {
type_parameters.append (p);
p.type = this;
/**
* Adds the specified class or interface to the list of base types of
* this class.
*
* @param type a class or interface reference
*/
public void add_base_type (TypeReference! type) {
base_types.append (type);
}
/**
* Returns a copy of the base type list.
*
* @return list of base types
*/
public ref List<TypeReference> get_base_types () {
return base_types.copy ();
}
/**
* Appends the specified parameter to the list of type parameters.
*
* @param p a type parameter
*/
public void add_type_parameter (TypeParameter! p) {
type_parameters.append (p);
p.type = this;
}
/**
* Adds the specified constant as a member to this class.
*
* @param c a constant
*/
public void add_constant (Constant! c) {
constants.append (c);
}
/**
* Adds the specified field as a member to this class.
*
* @param f a field
*/
public void add_field (Field! f) {
fields.append (f);
if (f.access == MemberAccessibility.PRIVATE) {
_has_private_fields = true;
}
}
/**
* Returns a copy of the list of fields.
*
* @return list of fields
*/
public ref List<Field> get_fields () {
return fields.copy ();
}
/**
* Adds the specified method as a member to this class.
*
* @param m a method
*/
public void add_method (Method! m) {
methods.append (m);
}
/**
* Returns a copy of the list of methods.
*
* @return list of methods
*/
public ref List<Method> get_methods () {
return methods.copy ();
}
/**
* Adds the specified property as a member to this class.
*
* @param prop a property
*/
public void add_property (Property! prop) {
properties.append (prop);
public void add_constant (Constant! c) {
constants.append (c);
if (prop.set_accessor != null && prop.set_accessor.body == null) {
/* automatic property accessor body generation */
var f = new Field (name = "_%s".printf (prop.name), type_reference = prop.type_reference, source_reference = prop.source_reference);
f.access = MemberAccessibility.PRIVATE;
add_field (f);
}
}
/**
* Returns a copy of the list of properties.
*
* @return list of properties
*/
public ref List<Property> get_properties () {
return properties.copy ();
}
/**
* Adds the specified signal as a member to this class.
*
* @param sig a signal
*/
public void add_signal (Signal! sig) {
signals.append (sig);
}
/**
* Returns a copy of the list of signals.
*
* @return list of signals
*/
public ref List<Signal> get_signals () {
return signals.copy ();
}
public override void accept (CodeVisitor! visitor) {
visitor.visit_begin_class (this);
public void add_field (Field! f) {
fields.append (f);
if (f.access == MemberAccessibility.PRIVATE) {
has_private_fields = true;
}
foreach (TypeReference type in base_types) {
type.accept (visitor);
}
public ref List<Field> get_fields () {
return fields.copy ();
foreach (TypeParameter p in type_parameters) {
p.accept (visitor);
}
public void add_method (Method! m) {
methods.append (m);
foreach (Field f in fields) {
f.accept (visitor);
}
public ref List<Method> get_methods () {
return methods.copy ();
foreach (Constant c in constants) {
c.accept (visitor);
}
public void add_property (Property! prop) {
properties.append (prop);
if (prop.set_accessor != null && prop.set_accessor.body == null) {
/* automatic property accessor body generation */
var f = new Field (name = "_%s".printf (prop.name), type_reference = prop.type_reference, source_reference = prop.source_reference);
f.access = MemberAccessibility.PRIVATE;
add_field (f);
}
foreach (Method m in methods) {
m.accept (visitor);
}
public ref List<Property> get_properties () {
return properties.copy ();
foreach (Property prop in properties) {
prop.accept (visitor);
}
public void add_signal (Signal! sig) {
signals.append (sig);
foreach (Signal sig in signals) {
sig.accept (visitor);
}
public ref List<Signal> get_signals () {
return signals.copy ();
if (constructor != null) {
constructor.accept (visitor);
}
public override void accept (CodeVisitor! visitor) {
visitor.visit_begin_class (this);
foreach (TypeReference 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);
}
foreach (Property prop in properties) {
prop.accept (visitor);
}
foreach (Signal sig in signals) {
sig.accept (visitor);
}
if (constructor != null) {
constructor.accept (visitor);
}
if (destructor != null) {
destructor.accept (visitor);
}
visitor.visit_end_class (this);
}
public override string get_cname () {
if (cname == null) {
cname = "%s%s".printf (@namespace.get_cprefix (), name);
}
return cname;
}
public void set_cname (string! cname) {
this.cname = cname;
}
public string get_lower_case_csuffix () {
if (lower_case_csuffix == null) {
lower_case_csuffix = Namespace.camel_case_to_lower_case (name);
}
return lower_case_csuffix;
if (destructor != null) {
destructor.accept (visitor);
}
public void set_lower_case_csuffix (string! csuffix) {
this.lower_case_csuffix = csuffix;
visitor.visit_end_class (this);
}
public override string get_cname () {
if (cname == null) {
cname = "%s%s".printf (@namespace.get_cprefix (), name);
}
public override ref string get_lower_case_cname (string infix) {
if (infix == null) {
infix = "";
}
return "%s%s%s".printf (@namespace.get_lower_case_cprefix (), infix, get_lower_case_csuffix ());
return cname;
}
/**
* Sets the name of this class as it is used in C code.
*
* @param cname the name to be used in C code
*/
public void set_cname (string! cname) {
this.cname = cname;
}
/**
* Returns the string to be prepended to the name of members of this
* class when used in C code.
*
* @return the suffix to be used in C code
*/
public string get_lower_case_csuffix () {
if (lower_case_csuffix == null) {
lower_case_csuffix = Namespace.camel_case_to_lower_case (name);
}
public override ref string get_upper_case_cname (string! infix) {
return get_lower_case_cname (infix).up ();
return lower_case_csuffix;
}
/**
* Sets the string to be prepended to the name of members of this class
* when used in C code.
*
* @param csuffix the suffix to be used in C code
*/
public void set_lower_case_csuffix (string! csuffix) {
this.lower_case_csuffix = csuffix;
}
public override ref string get_lower_case_cname (string infix) {
if (infix == null) {
infix = "";
}
return "%s%s%s".printf (@namespace.get_lower_case_cprefix (), infix, get_lower_case_csuffix ());
}
public override ref string get_upper_case_cname (string! infix) {
return get_lower_case_cname (infix).up ();
}
public override bool is_reference_type () {
return true;
}
void process_ccode_attribute (Attribute! a) {
foreach (NamedArgument arg in a.args) {
if (arg.name == "cname") {
/* this will already be checked during semantic analysis */
if (arg.argument is LiteralExpression) {
var lit = ((LiteralExpression) arg.argument).literal;
if (lit is StringLiteral) {
set_cname (((StringLiteral) lit).eval ());
}
public override bool is_reference_type () {
return true;
}
private void process_ccode_attribute (Attribute! a) {
foreach (NamedArgument arg in a.args) {
if (arg.name == "cname") {
/* this will already be checked during semantic analysis */
if (arg.argument is LiteralExpression) {
var lit = ((LiteralExpression) arg.argument).literal;
if (lit is StringLiteral) {
set_cname (((StringLiteral) lit).eval ());
}
} else if (arg.name == "cheader_filename") {
/* this will already be checked during semantic analysis */
if (arg.argument is LiteralExpression) {
var lit = ((LiteralExpression) arg.argument).literal;
if (lit is StringLiteral) {
var val = ((StringLiteral) lit).eval ();
foreach (string filename in val.split (",")) {
add_cheader_filename (filename);
}
}
} else if (arg.name == "cheader_filename") {
/* this will already be checked during semantic analysis */
if (arg.argument is LiteralExpression) {
var lit = ((LiteralExpression) arg.argument).literal;
if (lit is StringLiteral) {
var val = ((StringLiteral) lit).eval ();
foreach (string filename in val.split (",")) {
add_cheader_filename (filename);
}
}
}
}
}
public void process_attributes () {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
}
}
/**
* Process all associated attributes.
*/
public void process_attributes () {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
}
}
}
public override bool is_reference_counting () {
return true;
}
public override string get_ref_function () {
return "g_object_ref";
}
public override string get_unref_function () {
return "g_object_unref";
}
public override bool is_reference_counting () {
return true;
}
public override string get_ref_function () {
return "g_object_ref";
}
public override string get_unref_function () {
return "g_object_unref";
}
}
......@@ -490,6 +490,10 @@ namespace Vala {
var cswitch = new CCodeSwitchStatement (expression = new CCodeIdentifier (name = "property_id"));
var props = cl.get_properties ();
foreach (Property prop in props) {
if (prop.get_accessor == null) {
continue;
}
var ccase = new CCodeCaseStatement (expression = new CCodeIdentifier (name = prop.get_upper_case_cname ()));