Commit 15e891a3 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

Support type checks for error domains and error codes

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

	* vala/valaerrorcode.vala:
	* vala/valaerrordomain.vala:
	* vala/valaerrortype.vala:
	* vala/valasemanticanalyzer.vala:
	* vala/valasymbolresolver.vala:
	* gobject/valaccodegenerator.vala:
	* vapigen/valagirparser.vala:

	Support type checks for error domains and error codes

svn path=/trunk/; revision=1919
parent 10d24311
2008-10-25 Jürg Billeter <j@bitron.ch>
* vala/valaerrorcode.vala:
* vala/valaerrordomain.vala:
* vala/valaerrortype.vala:
* vala/valasemanticanalyzer.vala:
* vala/valasymbolresolver.vala:
* gobject/valaccodegenerator.vala:
* vapigen/valagirparser.vala:
Support type checks for error domains and error codes
2008-10-25 Jürg Billeter <j@bitron.ch>
* vala/valasemanticanalyzer.vala:
......
......@@ -3450,7 +3450,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
var ctemp = new CCodeIdentifier (temp_decl.name);
var cinit = new CCodeAssignment (ctemp, (CCodeExpression) expr.inner.ccodenode);
var ccheck = create_type_check (ctemp, expr.type_reference.data_type);
var ccheck = create_type_check (ctemp, expr.type_reference);
var ccast = new CCodeCastExpression (ctemp, expr.type_reference.get_cname ());
var cnull = new CCodeConstant ("NULL");
......@@ -3644,14 +3644,27 @@ public class Vala.CCodeGenerator : CodeGenerator {
}
}
CCodeFunctionCall create_type_check (CCodeNode ccodenode, TypeSymbol type) {
var ccheck = new CCodeFunctionCall (new CCodeIdentifier (get_type_check_function (type)));
ccheck.add_argument ((CCodeExpression) ccodenode);
return ccheck;
CCodeExpression create_type_check (CCodeNode ccodenode, DataType type) {
var et = type as ErrorType;
if (et != null && et.error_code != null) {
var matches_call = new CCodeFunctionCall (new CCodeIdentifier ("g_error_matches"));
matches_call.add_argument ((CCodeExpression) ccodenode);
matches_call.add_argument (new CCodeIdentifier (et.error_domain.get_upper_case_cname ()));
matches_call.add_argument (new CCodeIdentifier (et.error_code.get_cname ()));
return matches_call;
} else if (et != null && et.error_domain != null) {
var instance_domain = new CCodeMemberAccess.pointer ((CCodeExpression) ccodenode, "domain");
var type_domain = new CCodeIdentifier (et.error_domain.get_upper_case_cname ());
return new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, instance_domain, type_domain);
} else {
var ccheck = new CCodeFunctionCall (new CCodeIdentifier (get_type_check_function (type.data_type)));
ccheck.add_argument ((CCodeExpression) ccodenode);
return ccheck;
}
}
public override void visit_type_check (TypeCheck expr) {
expr.ccodenode = create_type_check (expr.expression.ccodenode, expr.type_reference.data_type);
expr.ccodenode = create_type_check (expr.expression.ccodenode, expr.type_reference);
}
public override void visit_conditional_expression (ConditionalExpression expr) {
......@@ -4135,7 +4148,9 @@ public class Vala.CCodeGenerator : CodeGenerator {
} else if (sym is Enum) {
type = new ValueType ((Enum) sym);
} else if (sym is ErrorDomain) {
type = new ErrorType ((ErrorDomain) sym);
type = new ErrorType ((ErrorDomain) sym, null);
} else if (sym is ErrorCode) {
type = new ErrorType ((ErrorDomain) sym.parent_symbol, (ErrorCode) sym);
} else {
Report.error (null, "internal error: `%s' is not a supported type".printf (sym.get_full_name ()));
return new InvalidType ();
......
......@@ -25,7 +25,7 @@ using GLib;
/**
* Represents an enum member in the source code.
*/
public class Vala.ErrorCode : Symbol {
public class Vala.ErrorCode : TypeSymbol {
/**
* Specifies the numerical representation of this enum value.
*/
......@@ -69,12 +69,7 @@ public class Vala.ErrorCode : Symbol {
}
}
/**
* Returns the name of this error code as it is used in C code.
*
* @return the name to be used in C code
*/
public string get_cname () {
public override string get_cname (bool const_type = false) {
if (cname == null) {
var edomain = (ErrorDomain) parent_symbol;
cname = "%s%s".printf (edomain.get_cprefix (), name);
......
......@@ -139,7 +139,7 @@ public class Vala.ErrorDomain : TypeSymbol {
}
public override string? get_upper_case_cname (string? infix) {
return get_lower_case_cname (null).up ();
return get_lower_case_cname (infix).up ();
}
public override bool is_reference_type () {
......
......@@ -32,9 +32,15 @@ public class Vala.ErrorType : ReferenceType {
*/
public weak ErrorDomain? error_domain { get; set; }
public ErrorType (ErrorDomain? error_domain, SourceReference? source_reference = null) {
/**
* The error code or null for generic error.
*/
public weak ErrorCode? error_code { get; set; }
public ErrorType (ErrorDomain? error_domain, ErrorCode? error_code, SourceReference? source_reference = null) {
this.error_domain = error_domain;
this.data_type = error_domain;
this.error_code = error_code;
this.source_reference = source_reference;
}
......@@ -57,7 +63,15 @@ public class Vala.ErrorType : ReferenceType {
}
/* otherwhise the error_domain has to be equal */
return et.error_domain == error_domain;
if (et.error_domain != error_domain) {
return false;
}
if (et.error_code == null) {
return true;
}
return et.error_code == error_code;
}
public override string to_qualified_string (Scope? scope) {
......@@ -69,8 +83,7 @@ public class Vala.ErrorType : ReferenceType {
}
public override DataType copy () {
var result = new ErrorType (error_domain, source_reference);
result.source_reference = source_reference;
var result = new ErrorType (error_domain, error_code, source_reference);
result.value_owned = value_owned;
result.nullable = nullable;
......
......@@ -1241,7 +1241,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
public override void visit_throw_statement (ThrowStatement stmt) {
stmt.error_expression.target_type = new ErrorType (null, stmt.source_reference);
stmt.error_expression.target_type = new ErrorType (null, null, stmt.source_reference);
stmt.error_expression.target_type.value_owned = true;
stmt.accept_children (this);
......@@ -1265,7 +1265,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
clause.body.scope.add (clause.variable_name, clause.error_variable);
clause.body.add_local_variable (clause.error_variable);
} else {
clause.error_type = new ErrorType (null, clause.source_reference);
clause.error_type = new ErrorType (null, null, clause.source_reference);
}
clause.accept_children (this);
......@@ -1700,7 +1700,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
var m = new DynamicMethod (expr.inner.value_type, expr.member_name, ret_type, expr.source_reference);
m.invocation = invoc;
m.add_error_type (new ErrorType (null));
m.add_error_type (new ErrorType (null, null));
m.access = SymbolAccessibility.PUBLIC;
m.add_parameter (new FormalParameter.with_ellipsis ());
dynamic_object_type.type_symbol.scope.add (null, m);
......@@ -1911,7 +1911,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
} else if (sym is Enum) {
type = new ValueType ((Enum) sym);
} else if (sym is ErrorDomain) {
type = new ErrorType ((ErrorDomain) sym);
type = new ErrorType ((ErrorDomain) sym, null);
} else if (sym is ErrorCode) {
type = new ErrorType ((ErrorDomain) sym.parent_symbol, (ErrorCode) sym);
} else {
Report.error (null, "internal error: `%s' is not a supported type".printf (sym.get_full_name ()));
return new InvalidType ();
......@@ -2708,10 +2710,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
if (ma != null) {
type_args = ma.get_type_arguments ();
}
} else if (constructor_sym is ErrorCode) {
type_sym = constructor_sym.parent_symbol;
expr.symbol_reference = constructor_sym;
}
if (type_sym is Class) {
......@@ -2720,11 +2718,12 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
} else if (type_sym is Struct) {
type = (TypeSymbol) type_sym;
expr.type_reference = new ValueType (type);
} else if (type_sym is ErrorDomain) {
expr.type_reference = new ErrorType ((ErrorDomain) type_sym, expr.source_reference);
} else if (type_sym is ErrorCode) {
expr.type_reference = new ErrorType ((ErrorDomain) type_sym.parent_symbol, (ErrorCode) type_sym, expr.source_reference);
expr.symbol_reference = type_sym;
} else {
expr.error = true;
Report.error (expr.source_reference, "`%s' is not a class, struct, or error domain".printf (type_sym.get_full_name ()));
Report.error (expr.source_reference, "`%s' is not a class, struct, or error code".printf (type_sym.get_full_name ()));
return;
}
......
......@@ -269,7 +269,7 @@ public class Vala.SymbolResolver : CodeVisitor {
} else if (sym is Class) {
var cl = (Class) sym;
if (cl.is_error_base) {
type = new ErrorType (null, unresolved_type.source_reference);
type = new ErrorType (null, null, unresolved_type.source_reference);
} else {
type = new ObjectType (cl);
}
......@@ -280,7 +280,9 @@ public class Vala.SymbolResolver : CodeVisitor {
} else if (sym is Enum) {
type = new ValueType ((Enum) sym);
} else if (sym is ErrorDomain) {
type = new ErrorType ((ErrorDomain) sym, unresolved_type.source_reference);
type = new ErrorType ((ErrorDomain) sym, null, unresolved_type.source_reference);
} else if (sym is ErrorCode) {
type = new ErrorType ((ErrorDomain) sym.parent_symbol, (ErrorCode) sym, unresolved_type.source_reference);
} else {
Report.error (unresolved_type.source_reference, "internal error: `%s' is not a supported type".printf (sym.get_full_name ()));
return new InvalidType ();
......
......@@ -709,7 +709,7 @@ public class Vala.GirParser : CodeVisitor {
end_element ("parameters");
}
if (throws_string == "1") {
m.add_error_type (new ErrorType (null));
m.add_error_type (new ErrorType (null, null));
}
end_element ("method");
return m;
......@@ -745,7 +745,7 @@ public class Vala.GirParser : CodeVisitor {
end_element ("parameters");
}
if (throws_string == "1") {
m.add_error_type (new ErrorType (null));
m.add_error_type (new ErrorType (null, null));
}
end_element ("callback");
return m;
......
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