Commit 1a6a0b20 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter
Browse files

support base access update test base access update

2006-10-25  Jürg Billeter  <j@bitron.ch>

	* vala/parser.y, vala/valacodevisitor.vala,
	  vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala,
	  vala/valabaseaccess.vala: support base access
	* vala/vala.h, vala/Makefile.am: update
	* tests/test-025.vala: test base access
	* tests/Makefile.am: update

svn path=/trunk/; revision=150
parent 41bbcfb9
2006-10-25 Jürg Billeter <j@bitron.ch>
* vala/parser.y, vala/valacodevisitor.vala,
vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala,
vala/valabaseaccess.vala: support base access
* vala/vala.h, vala/Makefile.am: update
* tests/test-025.vala: test base access
* tests/Makefile.am: update
2006-10-25 Jürg Billeter <j@bitron.ch>
* configure.ac: Post-release version bump
......
......@@ -25,4 +25,5 @@ EXTRA_DIST = \
test-022.vala \
test-023.vala \
test-024.vala \
test-025.vala \
$(NULL)
using GLib;
class Maman.Bar {
public virtual void do_action () {
stdout.printf (" 3");
}
}
class Maman.SubBar : Bar {
public override void do_action () {
stdout.printf (" BAD");
}
public void run () {
stdout.printf (" 2");
base.do_action ();
stdout.printf (" 4");
}
static int main (string[] args) {
stdout.printf ("Base Access Test: 1");
var bar = new SubBar ();
bar.run ();
stdout.printf (" 5\n");
return 0;
}
}
......@@ -31,6 +31,9 @@ libvala_la_SOURCES = \
valaattributeprocessor.c \
valaattributeprocessor.h \
valaattributeprocessor.vala \
valabaseaccess.c \
valabaseaccess.h \
valabaseaccess.vala \
valabinaryexpression.c \
valabinaryexpression.h \
valabinaryexpression.vala \
......@@ -306,6 +309,7 @@ valainclude_HEADERS = \
valaassignment.h \
valaattribute.h \
valaattributeprocessor.h \
valabaseaccess.h \
valabinaryexpression.h \
valablock.h \
valabooleanliteral.h \
......
......@@ -742,7 +742,7 @@ base_access
: BASE
{
ValaSourceReference *src = src(@1);
$$ = VALA_EXPRESSION (vala_member_access_new (NULL, "base", src));
$$ = VALA_EXPRESSION (vala_base_access_new (src));
g_object_unref (src);
}
;
......
#include <vala/valaarraycreationexpression.h>
#include <vala/valaassignment.h>
#include <vala/valaattribute.h>
#include <vala/valabaseaccess.h>
#include <vala/valabinaryexpression.h>
#include <vala/valablock.h>
#include <vala/valabooleanliteral.h>
......
/* valabaseaccess.vala
*
* Copyright (C) 2006 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 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>
*/
using GLib;
/**
* Represents an access to base class members in the source code.
*/
public class Vala.BaseAccess : Expression {
/**
* Creates a new base access expression.
*
* @param source reference to source code
* @return newly created base access expression
*/
public construct (SourceReference source = null) {
source_reference = source;
}
public override void accept (CodeVisitor! visitor) {
visitor.visit_base_access (this);
}
public override ref string! to_string () {
return "base";
}
}
......@@ -432,6 +432,19 @@ public class Vala.CodeGenerator : CodeVisitor {
ref CCodeFunctionCall ccall;
/* save pointer to parent class */
var parent_decl = new CCodeDeclaration ("gpointer");
var parent_var_decl = new CCodeVariableDeclarator ("%s_parent_class".printf (cl.get_lower_case_cname (null)));
parent_var_decl.initializer = new CCodeConstant ("NULL");
parent_decl.add_declarator (parent_var_decl);
parent_decl.modifiers = CCodeModifiers.STATIC;
source_type_member_declaration.append (parent_decl);
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
ccall.add_argument (new CCodeIdentifier ("klass"));
var parent_assignment = new CCodeAssignment (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))), ccall);
init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
/* add struct for private fields */
if (cl.has_private_fields) {
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
ccall.add_argument (new CCodeIdentifier ("klass"));
......@@ -439,23 +452,27 @@ public class Vala.CodeGenerator : CodeVisitor {
init_block.add_statement (new CCodeExpressionStatement (ccall));
}
/* set property handlers */
ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccall.add_argument (new CCodeIdentifier ("klass"));
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null))))));
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null))))));
/* set constructor */
if (cl.constructor != null) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccast.add_argument (new CCodeIdentifier ("klass"));
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null))))));
}
/* set dispose function */
if (memory_management && cl.get_fields () != null) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccast.add_argument (new CCodeIdentifier ("klass"));
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "dispose"), new CCodeIdentifier ("%s_dispose".printf (cl.get_lower_case_cname (null))))));
}
/* connect overridden methods */
var methods = cl.get_methods ();
foreach (Method m in methods) {
if (!m.is_virtual && !m.overrides) {
......@@ -472,6 +489,7 @@ public class Vala.CodeGenerator : CodeVisitor {
init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.name), new CCodeIdentifier (m.get_real_cname ()))));
}
/* create properties */
var props = cl.get_properties ();
foreach (Property prop in props) {
var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
......@@ -545,6 +563,7 @@ public class Vala.CodeGenerator : CodeVisitor {
init_block.add_statement (new CCodeExpressionStatement (cinst));
}
/* create signals */
foreach (Signal sig in cl.get_signals ()) {
var csignew = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_new"));
csignew.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
......@@ -2355,6 +2374,16 @@ public class Vala.CodeGenerator : CodeVisitor {
private void process_cmember (MemberAccess! expr, CCodeExpression pub_inst, DataType base_type) {
if (expr.symbol_reference.node is Method) {
var m = (Method) expr.symbol_reference.node;
if (expr.inner is BaseAccess && (m.is_virtual || m.overrides)) {
var base_class = (Class) m.base_method.symbol.parent_symbol.node;
var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
return;
}
if (!m.overrides) {
expr.ccodenode = new CCodeIdentifier (m.get_cname ());
} else {
......@@ -2785,6 +2814,10 @@ public class Vala.CodeGenerator : CodeVisitor {
visit_expression (expr);
}
public override void visit_base_access (BaseAccess! expr) {
expr.ccodenode = new InstanceCast (new CCodeIdentifier ("self"), expr.static_type.data_type);
}
public override void visit_postfix_expression (PostfixExpression! expr) {
var op = expr.increment ? CCodeUnaryOperator.POSTFIX_INCREMENT : CCodeUnaryOperator.POSTFIX_DECREMENT;
......
......@@ -627,6 +627,14 @@ public abstract class Vala.CodeVisitor {
public virtual void visit_element_access (ElementAccess! expr) {
}
/**
* Visit operation called for base access expressions.
*
* @param expr a base access expression
*/
public virtual void visit_base_access (BaseAccess! expr) {
}
/**
* Visit operation called for postfix expressions.
*
......
......@@ -777,9 +777,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
return;
}
if (expr.inner is MemberAccess) {
var base_expr = (MemberAccess) expr.inner;
base_symbol = base_expr.symbol_reference;
if (expr.inner is MemberAccess || expr.inner is BaseAccess) {
base_symbol = expr.inner.symbol_reference;
if (base_symbol.node is Namespace ||
base_symbol.node is DataType) {
expr.symbol_reference = base_symbol.lookup (expr.member_name);
......@@ -1031,6 +1030,18 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
}
}
public override void visit_base_access (BaseAccess! expr) {
if (current_class == null) {
expr.error = true;
Report.error (expr.source_reference, "Base access invalid outside of a class");
return;
}
expr.symbol_reference = current_class.symbol;
expr.static_type = new TypeReference ();
expr.static_type.data_type = current_class.base_class;
}
public override void visit_postfix_expression (PostfixExpression! expr) {
expr.static_type = expr.inner.static_type;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment