]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Use strict non-null types with --enable-experimental-non-null 80c18a1d1ff357be7f1d0f50f1aa331f206a0a0a
authorJürg Billeter <j@bitron.ch>
Sun, 18 Oct 2009 14:04:08 +0000 (16:04 +0200)
committerJürg Billeter <j@bitron.ch>
Sun, 18 Oct 2009 14:04:08 +0000 (16:04 +0200)
Do not consider local variables nullable or nullable types compatible
to non-null types when using --enable-experimental-non-null.

compiler/valacompiler.vala
vala/Makefile.am
vala/valacodecontext.vala
vala/valadatatype.vala
vala/valanullchecker.vala [deleted file]
vala/valanulltype.vala
vala/valasymbolresolver.vala
vapi/glib-2.0.vapi

index f2b023408956d648019c2976b3c9e7563202e6c1..b7e53505da4aa31c6413069e1810bd07544ee0b5 100644 (file)
@@ -55,7 +55,7 @@ class Vala.Compiler {
        static bool enable_checking;
        static bool deprecated;
        static bool experimental;
-       static bool non_null_experimental;
+       static bool experimental_non_null;
        static bool disable_dbus_transformation;
        static bool disable_warnings;
        static string cc_command;
@@ -101,7 +101,7 @@ class Vala.Compiler {
                { "enable-deprecated", 0, 0, OptionArg.NONE, ref deprecated, "Enable deprecated features", null },
                { "enable-experimental", 0, 0, OptionArg.NONE, ref experimental, "Enable experimental features", null },
                { "disable-warnings", 0, 0, OptionArg.NONE, ref disable_warnings, "Disable warnings", null },
-               { "enable-non-null-experimental", 0, 0, OptionArg.NONE, ref non_null_experimental, "Enable experimental enhancements for non-null types", null },
+               { "enable-experimental-non-null", 0, 0, OptionArg.NONE, ref experimental_non_null, "Enable experimental enhancements for non-null types", null },
                { "disable-dbus-transformation", 0, 0, OptionArg.NONE, ref disable_dbus_transformation, "Disable transformation of D-Bus member names", null },
                { "cc", 0, 0, OptionArg.STRING, ref cc_command, "Use COMMAND as C compiler command", "COMMAND" },
                { "Xcc", 'X', 0, OptionArg.STRING_ARRAY, ref cc_options, "Pass OPTION to the C compiler", "OPTION..." },
@@ -188,7 +188,7 @@ class Vala.Compiler {
                context.checking = enable_checking;
                context.deprecated = deprecated;
                context.experimental = experimental;
-               context.non_null_experimental = non_null_experimental;
+               context.experimental_non_null = experimental || experimental_non_null;
                context.dbus_transformation = !disable_dbus_transformation;
                context.report.enable_warnings = !disable_warnings;
                context.report.set_verbose_errors (!quiet_mode);
@@ -355,15 +355,6 @@ class Vala.Compiler {
                        return quit ();
                }
 
-               if (context.non_null_experimental) {
-                       var null_checker = new NullChecker ();
-                       null_checker.check (context);
-
-                       if (context.report.get_errors () > 0) {
-                               return quit ();
-                       }
-               }
-
                context.codegen.emit (context);
                
                if (context.report.get_errors () > 0) {
index db4d5c24277fbf0b84fe82d41db61f5ab8ace87f..39550615e6c271b8fb75b06a29ae5a8bdb2fc3d3 100644 (file)
@@ -98,7 +98,6 @@ libvalacore_la_VALASOURCES = \
        valamethodcall.vala \
        valamethodtype.vala \
        valanamespace.vala \
-       valanullchecker.vala \
        valanullliteral.vala \
        valanulltype.vala \
        valaobjectcreationexpression.vala \
index 938e51184081ef5137dd9057c52fda85103315c1..b079d9fecda7e96fe64de32b5537787c0e545f82 100644 (file)
@@ -49,7 +49,7 @@ public class Vala.CodeContext {
        /**
         * Enable experimental enhancements for non-null types.
         */
-       public bool non_null_experimental { get; set; }
+       public bool experimental_non_null { get; set; }
 
        /**
         * Enable transformation of D-Bus member names in dynamic client support.
index b792ef1d7a98d9c34807eff758bae948acef5741..b8b6cebab2b134490376b77fd18c7a2971ecf622 100644 (file)
@@ -297,6 +297,10 @@ public abstract class Vala.DataType : CodeNode {
        }
 
        public virtual bool compatible (DataType target_type) {
+               if (CodeContext.get ().experimental_non_null && nullable && !target_type.nullable) {
+                       return false;
+               }
+
                if (target_type.get_type_id () == "G_TYPE_VALUE" && get_type_id () != null) {
                        // allow implicit conversion to GValue
                        return true;
diff --git a/vala/valanullchecker.vala b/vala/valanullchecker.vala
deleted file mode 100644 (file)
index 8566fb7..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/* valanullchecker.vala
- *
- * Copyright (C) 2008-2009  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.1 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;
-
-/**
- * Code visitor checking null references.
- */
-public class Vala.NullChecker : CodeVisitor {
-       private CodeContext context;
-
-       DataType current_return_type;
-
-       public NullChecker () {
-       }
-
-       public void check (CodeContext context) {
-               this.context = context;
-
-               context.accept (this);
-       }
-
-       void check_compatible (Expression expr, DataType target_type) {
-               if (!target_type.nullable) {
-                       if (expr.value_type is NullType) {
-                               Report.error (expr.source_reference, "`null' incompatible with `%s'".printf (target_type.to_string ()));
-                       } else if (expr.value_type.nullable) {
-                               Report.warning (expr.source_reference, "`%s' incompatible with `%s'".printf (expr.value_type.to_string (), target_type.to_string ()));
-                       }
-               }
-       }
-
-       void check_non_null (Expression expr) {
-               if (expr.value_type is NullType) {
-                       Report.error (expr.source_reference, "null dereference");
-               } else if (expr.value_type.nullable) {
-                       Report.warning (expr.source_reference, "possible null dereference");
-               }
-       }
-
-       public override void visit_source_file (SourceFile file) {
-               file.accept_children (this);
-       }
-
-       public override void visit_class (Class cl) {
-               cl.accept_children (this);
-       }
-
-       public override void visit_struct (Struct st) {
-               st.accept_children (this);
-       }
-
-       public override void visit_interface (Interface iface) {
-               iface.accept_children (this);
-       }
-
-       public override void visit_enum (Enum en) {
-               en.accept_children (this);
-       }
-
-       public override void visit_error_domain (ErrorDomain ed) {
-               ed.accept_children (this);
-       }
-
-       public override void visit_field (Field f) {
-               f.accept_children (this);
-       }
-
-       public override void visit_method (Method m) {
-               var old_return_type = current_return_type;
-               current_return_type = m.return_type;
-
-               m.accept_children (this);
-
-               current_return_type = old_return_type;
-       }
-
-       public override void visit_creation_method (CreationMethod m) {
-               m.accept_children (this);
-       }
-
-       public override void visit_formal_parameter (FormalParameter p) {
-               p.accept_children (this);
-
-               if (p.default_expression != null) {
-                       check_compatible (p.default_expression, p.parameter_type);
-               }
-       }
-
-       public override void visit_property (Property prop) {
-               prop.accept_children (this);
-       }
-
-       public override void visit_property_accessor (PropertyAccessor acc) {
-               acc.accept_children (this);
-       }
-
-       public override void visit_constructor (Constructor c) {
-               c.accept_children (this);
-       }
-
-       public override void visit_destructor (Destructor d) {
-               d.accept_children (this);
-       }
-
-       public override void visit_block (Block b) {
-               b.accept_children (this);
-       }
-
-       public override void visit_local_variable (LocalVariable local) {
-               local.accept_children (this);
-
-               if (local.initializer != null) {
-                       check_compatible (local.initializer, local.variable_type);
-               }
-       }
-
-       public override void visit_expression_statement (ExpressionStatement stmt) {
-               stmt.accept_children (this);
-       }
-
-       public override void visit_if_statement (IfStatement stmt) {
-               stmt.accept_children (this);
-
-               check_non_null (stmt.condition);
-       }
-
-       public override void visit_switch_statement (SwitchStatement stmt) {
-               stmt.accept_children (this);
-       }
-
-       public override void visit_switch_section (SwitchSection section) {
-               section.accept_children (this);
-       }
-
-       public override void visit_loop (Loop stmt) {
-               stmt.accept_children (this);
-       }
-
-       public override void visit_foreach_statement (ForeachStatement stmt) {
-               stmt.accept_children (this);
-
-               check_non_null (stmt.collection);
-       }
-
-       public override void visit_return_statement (ReturnStatement stmt) {
-               stmt.accept_children (this);
-
-               if (stmt.return_expression != null) {
-                       check_compatible (stmt.return_expression, current_return_type);
-               }
-       }
-
-       public override void visit_yield_statement (YieldStatement stmt) {
-               stmt.accept_children (this);
-       }
-
-       public override void visit_throw_statement (ThrowStatement stmt) {
-               stmt.accept_children (this);
-
-               check_non_null (stmt.error_expression);
-       }
-
-       public override void visit_try_statement (TryStatement stmt) {
-               stmt.accept_children (this);
-       }
-
-       public override void visit_catch_clause (CatchClause clause) {
-               clause.accept_children (this);
-       }
-
-       public override void visit_delete_statement (DeleteStatement stmt) {
-               stmt.accept_children (this);
-       }
-
-       public override void visit_method_call (MethodCall expr) {
-               expr.accept_children (this);
-
-               var mtype = expr.call.value_type as MethodType;
-               var ma = expr.call as MemberAccess;
-               if (mtype != null && mtype.method_symbol.binding == MemberBinding.INSTANCE && ma != null) {
-                       check_non_null (ma.inner);
-               }
-       }
-
-       public override void visit_element_access (ElementAccess expr) {
-               expr.accept_children (this);
-
-               check_non_null (expr.container);
-       }
-
-       public override void visit_postfix_expression (PostfixExpression expr) {
-               check_non_null (expr.inner);
-       }
-
-       public override void visit_unary_expression (UnaryExpression expr) {
-               switch (expr.operator) {
-               case UnaryOperator.PLUS:
-               case UnaryOperator.MINUS:
-               case UnaryOperator.LOGICAL_NEGATION:
-               case UnaryOperator.BITWISE_COMPLEMENT:
-               case UnaryOperator.INCREMENT:
-               case UnaryOperator.DECREMENT:
-                       check_non_null (expr.inner);
-                       break;
-               }
-       }
-
-       public override void visit_reference_transfer_expression (ReferenceTransferExpression expr) {
-               expr.accept_children (this);
-       }
-
-       public override void visit_lambda_expression (LambdaExpression l) {
-               l.accept_children (this);
-       }
-
-       public override void visit_assignment (Assignment a) {
-               a.accept_children (this);
-
-               check_compatible (a.right, a.left.value_type);
-       }
-}
index f58cce38e0871937b23127990bd58cdfaa6dc67d..cbe0419535c3950e826f034a299e733360e0fff7 100644 (file)
@@ -1,6 +1,6 @@
 /* valanulltype.vala
  *
- * Copyright (C) 2007-2008  Jürg Billeter
+ * Copyright (C) 2007-2009  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
@@ -27,10 +27,15 @@ using GLib;
  */
 public class Vala.NullType : ReferenceType {
        public NullType (SourceReference source_reference) {
+               this.nullable = true;
                this.source_reference = source_reference;
        }
 
        public override bool compatible (DataType target_type) {
+               if (CodeContext.get ().experimental_non_null) {
+                       return target_type.nullable;
+               }
+
                if (!(target_type is PointerType) && (target_type is NullType || (target_type.data_type == null && target_type.type_parameter == null))) {
                        return true;
                }
@@ -64,4 +69,8 @@ public class Vala.NullType : ReferenceType {
        public override bool is_disposable () {
                return false;
        }
+
+       public override string to_qualified_string (Scope? scope = null) {
+               return "null";
+       }
 }
index 39fa9b94d08db37f68f466c5dece0c6f9bbd97e1..de3169633a64d4edc7cb87379d44095f7f10ea4e 100644 (file)
@@ -28,6 +28,7 @@ using GLib;
  * Code visitor resolving symbol names.
  */
 public class Vala.SymbolResolver : CodeVisitor {
+       CodeContext context;
        Symbol root_symbol;
        Scope current_scope;
        
@@ -37,6 +38,7 @@ public class Vala.SymbolResolver : CodeVisitor {
         * @param context a code context
         */
        public void resolve (CodeContext context) {
+               this.context = context;
                root_symbol = context.root;
 
                context.root.accept (this);
@@ -348,12 +350,16 @@ public class Vala.SymbolResolver : CodeVisitor {
 
        public override void visit_local_variable (LocalVariable local) {
                local.accept_children (this);
-               if (local.variable_type is ReferenceType) {
-                       var array_type = local.variable_type as ArrayType;
-                       if (array_type != null && array_type.fixed_length) {
-                               // local fixed length arrays are not nullable
-                       } else {
-                               local.variable_type.nullable = true;
+               if (!context.experimental_non_null) {
+                       // local reference variables are considered nullable
+                       // except when using experimental non-null enhancements
+                       if (local.variable_type is ReferenceType) {
+                               var array_type = local.variable_type as ArrayType;
+                               if (array_type != null && array_type.fixed_length) {
+                                       // local fixed length arrays are not nullable
+                               } else {
+                                       local.variable_type.nullable = true;
+                               }
                        }
                }
        }
index 2d313843fbefde399c3d9a44444d9a1cb8be87f8..d16c2ec1c5d2773f2283de1ef7dbb89cb67e9588 100644 (file)
@@ -2484,7 +2484,7 @@ namespace GLib {
 
                public string? read_line () {
                        int c;
-                       StringBuilder ret = null;
+                       StringBuilder? ret = null;
                        while ((c = getc ()) != EOF) {
                                if (ret == null) {
                                        ret = new StringBuilder ();
@@ -2494,7 +2494,11 @@ namespace GLib {
                                }
                                ret.append_c ((char) c);
                        }
-                       return ret == null ? null : ret.str;
+                       if (ret == null) {
+                               return null;
+                       } else {
+                               return ret.str;
+                       }
                }
        }