Commit ebf0ebfa authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

switch invocation expression to external visitor

2007-09-17  Juerg Billeter  <j@bitron.ch>

	* vala/valacodevisitor.vala, vala/valainvocationexpression.vala,
	  vala/valamemorymanager.vala, vala/valasemanticanalyzer.vala,
	  vala/valasymbolresolver.vala,
	  gobject/valacodegeneratorinvocationexpression.vala: switch invocation
	  expression to external visitor

svn path=/trunk/; revision=614
parent d4b0b21e
2007-09-17 Jürg Billeter <j@bitron.ch>
* vala/valacodevisitor.vala, vala/valainvocationexpression.vala,
vala/valamemorymanager.vala, vala/valasemanticanalyzer.vala,
vala/valasymbolresolver.vala,
gobject/valacodegeneratorinvocationexpression.vala: switch invocation
expression to external visitor
2007-09-17 Jürg Billeter <j@bitron.ch>
* vala/valacodevisitor.vala, vala/valamemorymanager.vala,
......
......@@ -25,7 +25,9 @@ using GLib;
using Gee;
public class Vala.CodeGenerator {
public override void visit_end_invocation_expression (InvocationExpression! expr) {
public override void visit_invocation_expression (InvocationExpression! expr) {
expr.accept_children (this);
var ccall = new CCodeFunctionCall ((CCodeExpression) expr.call.ccodenode);
Method m = null;
......
......@@ -468,19 +468,11 @@ public abstract class Vala.CodeVisitor : Object {
}
/**
* Visit operation called at beginning of invocation expressions.
* Visit operation called for invocation expressions.
*
* @param expr an invocation expression
*/
public virtual void visit_begin_invocation_expression (InvocationExpression! expr) {
}
/**
* Visit operation called at end of invocation expressions.
*
* @param expr an invocation expression
*/
public virtual void visit_end_invocation_expression (InvocationExpression! expr) {
public virtual void visit_invocation_expression (InvocationExpression! expr) {
}
/**
......
......@@ -31,9 +31,7 @@ public class Vala.InvocationExpression : Expression {
* The method to call.
*/
public Expression! call {
get {
return _call;
}
get { return _call; }
set construct {
_call = value;
_call.parent_node = this;
......@@ -90,15 +88,15 @@ public class Vala.InvocationExpression : Expression {
}
public override void accept (CodeVisitor! visitor) {
call.accept (visitor);
visitor.visit_invocation_expression (this);
}
visitor.visit_begin_invocation_expression (this);
public override void accept_children (CodeVisitor! visitor) {
call.accept (visitor);
foreach (Expression expr in argument_list) {
expr.accept (visitor);
}
visitor.visit_end_invocation_expression (this);
}
public override void replace (CodeNode! old_node, CodeNode! new_node) {
......
......@@ -202,7 +202,9 @@ public class Vala.MemoryManager : CodeVisitor {
}
}
public override void visit_end_invocation_expression (InvocationExpression! expr) {
public override void visit_invocation_expression (InvocationExpression! expr) {
expr.accept_children (this);
var msym = (Invokable) expr.call.symbol_reference;
Collection<FormalParameter> params = msym.get_parameters ();
......
......@@ -1470,7 +1470,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
return expression_type.data_type.is_subtype_of (expected_type.data_type);
}
public override void visit_begin_invocation_expression (InvocationExpression! expr) {
public override void visit_invocation_expression (InvocationExpression! expr) {
expr.call.accept (this);
if (expr.call.error) {
/* if method resolving didn't succeed, skip this check */
expr.error = true;
......@@ -1525,6 +1527,57 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
arg.expected_type = param.type_reference;
}
}
foreach (Expression arg in expr.get_argument_list ()) {
arg.accept (this);
}
TypeReference ret_type;
if (msym is Invokable) {
var m = (Invokable) msym;
ret_type = m.get_return_type ();
params = m.get_parameters ();
if (ret_type.data_type == null && ret_type.type_parameter == null) {
// void return type
if (!(expr.parent_node is ExpressionStatement)) {
expr.error = true;
Report.error (expr.source_reference, "invocation of void method not allowed as expression");
return;
}
}
// resolve generic return values
if (ret_type.type_parameter != null) {
if (!(expr.call is MemberAccess)) {
Report.error (((CodeNode) m).source_reference, "internal error: unsupported generic return value");
expr.error = true;
return;
}
var ma = (MemberAccess) expr.call;
if (ma.inner == null) {
// TODO resolve generic return values within the type hierarchy if possible
Report.error (expr.source_reference, "internal error: resolving generic return values within type hierarchy not supported yet");
expr.error = true;
return;
} else {
ret_type = get_actual_type (ma.inner.static_type, msym, ret_type, expr);
if (ret_type == null) {
return;
}
}
}
}
if (msym is Method) {
var m = (Method) msym;
expr.tree_can_fail = expr.can_fail = (m.get_error_domains ().size > 0);
}
expr.static_type = ret_type;
check_arguments (expr, msym, params, expr.get_argument_list ());
}
private bool check_arguments (Expression! expr, Symbol! msym, Collection<FormalParameter> params, Collection<Expression> args) {
......@@ -1612,62 +1665,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
return true;
}
public override void visit_end_invocation_expression (InvocationExpression! expr) {
if (expr.error) {
return;
}
var msym = expr.call.symbol_reference;
TypeReference ret_type;
Collection<FormalParameter> params;
if (msym is Invokable) {
var m = (Invokable) msym;
ret_type = m.get_return_type ();
params = m.get_parameters ();
if (ret_type.data_type == null && ret_type.type_parameter == null) {
// void return type
if (!(expr.parent_node is ExpressionStatement)) {
expr.error = true;
Report.error (expr.source_reference, "invocation of void method not allowed as expression");
return;
}
}
// resolve generic return values
if (ret_type.type_parameter != null) {
if (!(expr.call is MemberAccess)) {
Report.error (((CodeNode) m).source_reference, "internal error: unsupported generic return value");
expr.error = true;
return;
}
var ma = (MemberAccess) expr.call;
if (ma.inner == null) {
// TODO resolve generic return values within the type hierarchy if possible
Report.error (expr.source_reference, "internal error: resolving generic return values within type hierarchy not supported yet");
expr.error = true;
return;
} else {
ret_type = get_actual_type (ma.inner.static_type, msym, ret_type, expr);
if (ret_type == null) {
return;
}
}
}
}
if (msym is Method) {
var m = (Method) msym;
expr.tree_can_fail = expr.can_fail = (m.get_error_domains ().size > 0);
}
expr.static_type = ret_type;
check_arguments (expr, msym, params, expr.get_argument_list ());
}
public static TypeReference get_actual_type (TypeReference derived_instance_type, Symbol generic_member, TypeReference generic_type, CodeNode node_reference) {
TypeReference instance_type = derived_instance_type;
// trace type arguments back to the datatype where the method has been declared
......
......@@ -335,6 +335,10 @@ public class Vala.SymbolResolver : CodeVisitor {
e.accept_children (this);
}
public override void visit_invocation_expression (InvocationExpression! expr) {
expr.accept_children (this);
}
public override void visit_assignment (Assignment! a) {
a.accept_children (this);
}
......
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