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

Use non-null types by default when passing --enable-non-null to valac,

2008-01-09  Juerg Billeter  <j@bitron.ch>

	* vala/parser.y, vala/scanner.l, vala/valaclass.vala,
	  vala/valacodecontext.vala, vala/valadatatype.vala,
	  vala/valainterface.vala, vala/valanulltype.vala,
	  vala/valasemanticanalyzer.vala, vala/valasymbolresolver.vala,
	  vala/valaunresolvedtype.vala, gobject/valaccodegenerator.vala,
	  gobject/valaccodegeneratorinvocationexpression.vala,
	  gobject/valaccodegeneratormethod.vala, compiler/valacompiler.vala:

	  Use non-null types by default when passing --enable-non-null to valac,
	  `?´ marks nullable types, deprecate `!´ to mark non-null types,
	  fixes bug 504222

svn path=/trunk/; revision=810
parent 4c7f0c0f
2008-01-09 Jürg Billeter <j@bitron.ch>
* vala/parser.y, vala/scanner.l, vala/valaclass.vala,
vala/valacodecontext.vala, vala/valadatatype.vala,
vala/valainterface.vala, vala/valanulltype.vala,
vala/valasemanticanalyzer.vala, vala/valasymbolresolver.vala,
vala/valaunresolvedtype.vala, gobject/valaccodegenerator.vala,
gobject/valaccodegeneratorinvocationexpression.vala,
gobject/valaccodegeneratormethod.vala, compiler/valacompiler.vala:
Use non-null types by default when passing --enable-non-null to valac,
`?´ marks nullable types, deprecate `!´ to mark non-null types,
fixes bug 504222
2008-01-08 Jürg Billeter <j@bitron.ch>
* gobject/valaccodegenerator.vala: fix memory management with simple
......
/* valacompiler.vala
*
* Copyright (C) 2006-2007 Jürg Billeter
* Copyright (C) 2006-2008 Jürg Billeter
* Copyright (C) 1996-2002, 2004, 2005, 2006 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
......@@ -43,6 +43,7 @@ class Vala.Compiler : Object {
static int optlevel;
static bool disable_assert;
static bool disable_checking;
static bool non_null;
static string cc_command;
[NoArrayLength]
static string[] cc_options;
......@@ -65,6 +66,7 @@ class Vala.Compiler : Object {
{ "optimize", 'O', 0, OptionArg.INT, ref optlevel, "Optimization level", "OPTLEVEL" },
{ "disable-assert", 0, 0, OptionArg.NONE, ref disable_assert, "Disable assertions", null },
{ "disable-checking", 0, 0, OptionArg.NONE, ref disable_checking, "Disable run-time checks", null },
{ "enable-non-null", 0, 0, OptionArg.NONE, ref non_null, "Enable non-null types", null },
{ "cc", 0, 0, OptionArg.STRING, out cc_command, "Use COMMAND as C compiler command", "COMMAND" },
{ "Xcc", 'X', 0, OptionArg.STRING_ARRAY, out cc_options, "Pass OPTION to the C compiler", "OPTION..." },
{ "save-temps", 0, 0, OptionArg.NONE, out save_temps, "Keep temporary files", null },
......@@ -160,6 +162,7 @@ class Vala.Compiler : Object {
context.library = library;
context.assert = !disable_assert;
context.checking = !disable_checking;
context.non_null = non_null;
context.ccode_only = ccode_only;
context.compile_only = compile_only;
......
......@@ -1086,7 +1086,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
var cassign = new CCodeAssignment (cvar, ccomma);
// g_free (NULL) is allowed
if (type.non_null || (type.data_type != null && !type.data_type.is_reference_counting () && type.data_type.get_free_function () == "g_free")) {
if ((context.non_null && !type.nullable) || (type.data_type != null && !type.data_type.is_reference_counting () && type.data_type.get_free_function () == "g_free")) {
return new CCodeParenthesizedExpression (cassign);
}
......@@ -2226,7 +2226,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
var ccall = new CCodeFunctionCall (dupexpr);
if (expr.static_type.non_null && expr.static_type.type_parameter == null) {
if ((context.non_null && !expr.static_type.nullable) && expr.static_type.type_parameter == null) {
ccall.add_argument ((CCodeExpression) expr.ccodenode);
return ccall;
......
/* valaccodegeneratorinvocationexpression.vala
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -233,7 +233,7 @@ public class Vala.CCodeGenerator {
cexpr = get_implicit_cast_expression (cexpr, arg.static_type, param.type_reference);
// pass non-simple struct instances always by reference
if (param.type_reference.data_type is Struct && !((Struct) param.type_reference.data_type).is_simple_type ()) {
if (!(arg.static_type is NullType) && param.type_reference.data_type is Struct && !((Struct) param.type_reference.data_type).is_simple_type ()) {
// we already use a reference for arguments of ref and out parameters
if (!param.type_reference.is_ref && !param.type_reference.is_out) {
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
......
......@@ -281,7 +281,7 @@ public class Vala.CCodeGenerator {
var t = param.type_reference.data_type;
if (t != null && t.is_reference_type () && !param.type_reference.is_out) {
var type_check = create_method_type_check_statement (m, creturn_type, t, param.type_reference.non_null, param.name);
var type_check = create_method_type_check_statement (m, creturn_type, t, (context.non_null && !param.type_reference.nullable), param.name);
if (type_check != null) {
type_check.line = function.line;
cinit.append (type_check);
......
/* parser.y
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -113,6 +113,7 @@ static gboolean check_is_struct (ValaSymbol *symbol, ValaSourceReference *src);
%token SEMICOLON ";"
%token HASH "#"
%token INTERR "?"
%token NULLABLE_INTERR "nullable ?"
%token ASSIGN_BITWISE_OR "|="
%token ASSIGN_BITWISE_AND "&="
......@@ -290,6 +291,8 @@ static gboolean check_is_struct (ValaSymbol *symbol, ValaSourceReference *src);
%type <local_variable_declaration> local_variable_declaration
%type <type_reference> local_variable_type
%type <num> opt_op_neg
%type <num> opt_any_interr
%type <num> opt_nullable_interr
%type <statement> expression_statement
%type <expression> statement_expression
%type <statement> selection_statement
......@@ -502,68 +505,65 @@ stars
;
type
: type_name opt_rank_specifier opt_op_neg
: type_name opt_rank_specifier opt_op_neg opt_any_interr
{
$$ = $1;
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
if ($3) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
if ($4) {
vala_unresolved_type_set_nullable (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| WEAK type_name opt_rank_specifier opt_op_neg
| WEAK type_name opt_rank_specifier opt_op_neg opt_any_interr
{
$$ = $2;
vala_unresolved_type_set_is_weak (VALA_UNRESOLVED_TYPE ($$), TRUE);
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
if ($4) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
if ($5) {
vala_unresolved_type_set_nullable (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| type_name opt_rank_specifier opt_op_neg HASH
| type_name opt_rank_specifier opt_op_neg opt_any_interr HASH
{
$$ = $1;
vala_unresolved_type_set_transfers_ownership (VALA_UNRESOLVED_TYPE ($$), TRUE);
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
if ($3) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
if ($4) {
vala_unresolved_type_set_nullable (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| REF type_name opt_rank_specifier opt_op_neg
| REF type_name opt_rank_specifier opt_op_neg opt_any_interr
{
$$ = $2;
vala_unresolved_type_set_is_ref (VALA_UNRESOLVED_TYPE ($$), TRUE);
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
if ($4) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
if ($5) {
vala_unresolved_type_set_nullable (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| OUT type_name opt_rank_specifier opt_op_neg
| OUT type_name opt_rank_specifier opt_op_neg opt_any_interr
{
$$ = $2;
vala_unresolved_type_set_is_out (VALA_UNRESOLVED_TYPE ($$), TRUE);
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
if ($4) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
if ($5) {
vala_unresolved_type_set_nullable (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| OUT WEAK type_name opt_rank_specifier opt_op_neg
| OUT WEAK type_name opt_rank_specifier opt_op_neg opt_any_interr
{
$$ = $3;
vala_unresolved_type_set_is_weak (VALA_UNRESOLVED_TYPE ($$), TRUE);
vala_unresolved_type_set_is_out (VALA_UNRESOLVED_TYPE ($$), TRUE);
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $4);
if ($5) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
if ($6) {
vala_unresolved_type_set_nullable (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| type_name stars opt_rank_specifier opt_op_neg
| type_name stars opt_rank_specifier
{
$$ = $1;
vala_unresolved_type_set_pointer_level (VALA_UNRESOLVED_TYPE ($$), $2);
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
if ($4) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| VOID
{
......@@ -1325,7 +1325,7 @@ relational_expression
g_object_unref ($3);
}
}
| relational_expression IS type
| relational_expression IS type_name
{
if ($1 == NULL || $3 == NULL) {
// error in subexpression
......@@ -1338,7 +1338,7 @@ relational_expression
g_object_unref ($3);
}
}
| relational_expression AS type
| relational_expression AS type_name
{
if ($1 == NULL || $3 == NULL) {
// error in subexpression
......@@ -1859,7 +1859,7 @@ local_variable_declaration
/* don't use type to prevent reduce/reduce conflict */
local_variable_type
: primary_expression opt_bracket_pair opt_op_neg
: primary_expression opt_bracket_pair opt_op_neg opt_nullable_interr
{
ValaSourceReference *src = src(@1);
$$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression ($1));
......@@ -1867,8 +1867,8 @@ local_variable_type
g_object_unref (src);
vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($$), TRUE);
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
if ($3) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
if ($4) {
vala_unresolved_type_set_nullable (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| primary_expression stars
......@@ -1879,15 +1879,15 @@ local_variable_type
g_object_unref (src);
vala_unresolved_type_set_pointer_level (VALA_UNRESOLVED_TYPE ($$), $2);
}
| WEAK primary_expression opt_bracket_pair opt_op_neg
| WEAK primary_expression opt_bracket_pair opt_op_neg opt_nullable_interr
{
ValaSourceReference *src = src(@2);
$$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression ($2));
g_object_unref ($2);
g_object_unref (src);
vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
if ($4) {
vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
if ($5) {
vala_unresolved_type_set_nullable (VALA_UNRESOLVED_TYPE ($$), TRUE);
}
}
| VOID
......@@ -1922,6 +1922,32 @@ opt_op_neg
}
;
opt_any_interr
: /* empty */
{
$$ = FALSE;
}
| INTERR
{
$$ = TRUE;
}
| NULLABLE_INTERR
{
$$ = TRUE;
}
;
opt_nullable_interr
: /* empty */
{
$$ = FALSE;
}
| NULLABLE_INTERR
{
$$ = TRUE;
}
;
expression_statement
: comment statement_expression SEMICOLON
{
......
/* scanner.l
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -87,6 +87,7 @@ literal ({integer_literal}|{real_literal}|{character_literal}|{string_literal
"," { uploc; return COMMA; }
";" { uploc; return SEMICOLON; }
"#" { uploc; return HASH; }
"?"{space}({ident}("="|";")|"[") { yyless (1); uploc; return NULLABLE_INTERR; }
"?" { uploc; return INTERR; }
"|=" { uploc; return ASSIGN_BITWISE_OR; }
......
/* valaclass.vala
*
* Copyright (C) 2006-2007 Jürg Billeter
* Copyright (C) 2006-2008 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
......@@ -164,10 +164,6 @@ public class Vala.Class : Typesymbol {
* @param f a field
*/
public void add_field (Field! f) {
if (f.type_reference is UnresolvedType) {
// non_null fields not yet supported due to initialization issues
((UnresolvedType) f.type_reference).non_null = false;
}
fields.add (f);
if (f.access == SymbolAccessibility.PRIVATE && f.instance) {
_has_private_fields = true;
......@@ -232,8 +228,6 @@ public class Vala.Class : Typesymbol {
source_reference != null && !source_reference.file.pkg) {
/* automatic property accessor body generation */
var field_type = prop.type_reference.copy ();
// non_null fields not yet supported due to initialization issues
((UnresolvedType) field_type).non_null = false;
var f = new Field ("_%s".printf (prop.name), field_type, null, prop.source_reference);
f.access = SymbolAccessibility.PRIVATE;
add_field (f);
......
/* valacodecontext.vala
*
* Copyright (C) 2006-2007 Jürg Billeter
* Copyright (C) 2006-2008 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
......@@ -50,6 +50,14 @@ public class Vala.CodeContext : Object {
*/
public bool checking { get; set; }
/**
* Enable non-null types.
*/
public bool non_null {
get { return _non_null; }
set { _non_null = value; }
}
/**
* Output C code, don't compile to object code.
*/
......@@ -116,6 +124,8 @@ public class Vala.CodeContext : Object {
private Gee.List<string> packages = new ArrayList<string> (str_equal);
private static bool _non_null = false;
/**
* The root namespace of the symbol tree.
*
......@@ -137,6 +147,10 @@ public class Vala.CodeContext : Object {
codegen = new CodeGenerator ();
}
public static bool is_non_null_enabled () {
return _non_null;
}
/**
* Returns a copy of the list of source files.
*
......
/* valadatatype.vala
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -44,12 +44,12 @@ public class Vala.DataType : CodeNode {
* Specifies that the expression is a reference used in out parameters.
*/
public bool is_out { get; set; }
/**
* Specifies that the expression is guaranteed not to be null.
* Specifies that the expression may be null.
*/
public bool non_null { get; set; }
public bool nullable { get; set; }
/**
* Specifies that the expression is known to be null.
*/
......@@ -209,8 +209,8 @@ public class Vala.DataType : CodeNode {
}
s += ">";
}
if (non_null) {
s += "!";
if (nullable) {
s += "?";
}
return s;
......@@ -227,7 +227,7 @@ public class Vala.DataType : CodeNode {
result.transfers_ownership = transfers_ownership;
result.takes_ownership = takes_ownership;
result.is_out = is_out;
result.non_null = non_null;
result.nullable = nullable;
result.data_type = data_type;
result.type_parameter = type_parameter;
result.floating_reference = floating_reference;
......@@ -261,7 +261,7 @@ public class Vala.DataType : CodeNode {
if (type2.is_out != is_out) {
return false;
}
if (type2.non_null != non_null) {
if (type2.nullable != nullable) {
return false;
}
if (type2.data_type != data_type) {
......@@ -303,7 +303,7 @@ public class Vala.DataType : CodeNode {
return false;
}
if (type2.non_null && !non_null) {
if (!type2.nullable && nullable) {
return false;
}
......@@ -341,22 +341,6 @@ public class Vala.DataType : CodeNode {
return (data_type == null && type_parameter == null);
}
if (data_type == null) {
/* null can be cast to any reference or array type or pointer type */
if (target_type.type_parameter != null ||
target_type is PointerType ||
target_type.data_type.is_reference_type () ||
target_type.is_out ||
target_type.data_type is Array ||
target_type.data_type is Callback ||
target_type.data_type.get_attribute ("PointerType") != null) {
return true;
}
/* null is not compatible with any other type (i.e. value types) */
return false;
}
if (target_type is PointerType || (target_type.data_type != null && target_type.data_type.get_attribute ("PointerType") != null)) {
/* any reference or array type or pointer type can be cast to a generic pointer */
if (type_parameter != null ||
......
/* valainterface.vala
*
* Copyright (C) 2006-2007 Jürg Billeter
* Copyright (C) 2006-2008 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
......@@ -146,8 +146,6 @@ public class Vala.Interface : Typesymbol {
* @param f a field
*/
public void add_field (Field! f) {
// non_null fields not yet supported due to initialization issues
f.type_reference.non_null = false;
fields.add (f);
scope.add (f.name, f);
}
......
/* valanulltype.vala
*
* Copyright (C) 2007 Jürg Billeter
* Copyright (C) 2007-2008 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
......@@ -37,14 +37,18 @@ public class Vala.NullType : ReferenceType {
/* null can be cast to any reference or array type or pointer type */
if (target_type.type_parameter != null ||
target_type is PointerType ||
target_type.data_type.is_reference_type () ||
target_type.is_out ||
target_type.data_type is Array ||
target_type.data_type is Callback ||
target_type.nullable ||
target_type.data_type.get_attribute ("PointerType") != null) {
return true;
}
if (target_type.data_type.is_reference_type () ||
target_type.data_type is Array ||
target_type.data_type is Callback) {
return !(CodeContext.is_non_null_enabled ());
}
/* null is not compatible with any other type (i.e. value types) */
return false;
}
......
/* valasemanticanalyzer.vala
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -1148,7 +1148,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
public override void visit_string_literal (StringLiteral! expr) {
expr.static_type = string_type.copy ();
expr.static_type.non_null = true;
}
public override void visit_null_literal (NullLiteral! expr) {
......@@ -2370,7 +2369,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
base_type = new DataType ();
base_type.data_type = type.data_type;
base_type.type_parameter = type.type_parameter;
base_type.non_null = type.non_null;
base_type.nullable = type.nullable;
base_type.is_null = type.is_null;
base_type.transfers_ownership = type.transfers_ownership;
} else {
......@@ -2383,7 +2382,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
break;
}
}
base_type.non_null = base_type.non_null && type.non_null;
base_type.nullable = base_type.nullable || type.nullable;
base_type.is_null = base_type.is_null && type.is_null;
// if one subexpression transfers ownership, all subexpressions must transfer ownership
// FIXME add ref calls to subexpressions that don't transfer ownership
......
/* valasymbolresolver.vala
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -187,7 +187,7 @@ public class Vala.SymbolResolver : CodeVisitor {
type.transfers_ownership = unresolved_type.transfers_ownership;
type.is_ref = unresolved_type.is_ref;
type.is_out = unresolved_type.is_out;
type.non_null = unresolved_type.non_null;
type.nullable = unresolved_type.nullable;
foreach (DataType type_arg in unresolved_type.get_type_arguments ()) {
type.add_type_argument (type_arg);
}
......
/* valaunresolvedtype.vala
*
* Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -75,11 +75,11 @@ public class Vala.UnresolvedType : DataType {
* Specifies that the expression is a reference used in out parameters.
*/
public bool is_out { get; set; }
/**
* Specifies that the expression is guaranteed not to be null.
* Specifies that the expression may be null.
*/
public bool non_null { get; set; }
public bool nullable { get; set; }
public UnresolvedType () {
}
......@@ -141,7 +141,7 @@ public class Vala.UnresolvedType : DataType {
result.transfers_ownership = transfers_ownership;
result.takes_ownership = takes_ownership;
result.is_out = is_out;
result.non_null = non_null;
result.nullable = nullable;
result.namespace_name = namespace_name;
result.type_name = type_name;
result.array_rank = array_rank;
......
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