}
public override void visit_cast_expression (CastExpression expr) {
+ if (expr.is_non_null_cast) {
+ // TODO add NULL runtime check
+ expr.ccodenode = expr.inner.ccodenode;
+ return;
+ }
+
if (expr.inner.value_type != null && gvalue_type != null && expr.inner.value_type.data_type == gvalue_type
&& expr.type_reference.get_type_id () != null) {
// explicit conversion from GValue
*/
public bool is_silent_cast { get; set; }
+ public bool is_non_null_cast { get; set; }
+
private Expression _inner;
private DataType _data_type;
this.is_silent_cast = is_silent_cast;
this.inner = inner;
}
-
+
+ public CastExpression.non_null (Expression inner, SourceReference source_reference) {
+ this.inner = inner;
+ this.is_non_null_cast = true;
+ this.source_reference = source_reference;
+ }
+
public override void accept (CodeVisitor visitor) {
inner.accept (visitor);
- type_reference.accept (visitor);
+ if (!is_non_null_cast) {
+ type_reference.accept (visitor);
+ }
visitor.visit_cast_expression (this);
return false;
}
+ if (is_non_null_cast) {
+ // (!) non-null cast
+ value_type = inner.value_type.copy ();
+ value_type.nullable = false;
+
+ inner.target_type = inner.value_type.copy ();
+
+ return !error;
+ }
+
type_reference.check (analyzer);
// FIXME: check whether cast is allowed
}
public override void visit_cast_expression (CastExpression expr) {
+ if (expr.is_non_null_cast) {
+ write_string ("(!) ");
+ expr.inner.accept (this);
+ return;
+ }
+
if (!expr.is_silent_cast) {
write_string ("(");
write_type (expr.type_reference);
}
}
break;
+ case TokenType.OP_NEG:
+ next ();
+ if (accept (TokenType.CLOSE_PARENS)) {
+ // (!) non-null cast
+ var inner = parse_unary_expression ();
+ return new CastExpression.non_null (inner, get_src (begin));
+ }
+ break;
default:
break;
}