Merge: Fix asnotnull
authorJean Privat <jean@pryen.org>
Fri, 18 Jul 2014 02:32:41 +0000 (22:32 -0400)
committerJean Privat <jean@pryen.org>
Fri, 18 Jul 2014 13:26:52 +0000 (09:26 -0400)
Add warnings on useless as(not null)  (one less TODO) and fix the bug on non-null primitives.

Fixes #589

Pull-Request: #591
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>

29 files changed:
lib/neo4j/neo4j.nit
lib/opts.nit
lib/standard/ropes.nit
src/abstract_compiler.nit
src/common_ffi/c.nit
src/modelize_property.nit
src/naive_interpreter.nit
src/nit.nit
src/nitvm.nit
src/transform.nit
src/typing.nit
tests/base_as_notnull2.nit [new file with mode: 0644]
tests/base_as_notnull_int.nit [new file with mode: 0644]
tests/sav/base_as_notnull.res
tests/sav/base_as_notnull2.res [new file with mode: 0644]
tests/sav/base_as_notnull2_alt1.res [new file with mode: 0644]
tests/sav/base_as_notnull2_alt2.res [new file with mode: 0644]
tests/sav/base_as_notnull2_alt3.res [new file with mode: 0644]
tests/sav/base_as_notnull_alt1.res
tests/sav/base_as_notnull_alt2.res
tests/sav/base_as_notnull_alt3.res
tests/sav/base_as_notnull_alt4.res
tests/sav/base_as_notnull_alt5.res
tests/sav/base_as_notnull_alt6.res
tests/sav/base_as_notnull_alt7.res
tests/sav/base_as_notnull_int.res [new file with mode: 0644]
tests/sav/error_expr_not_ok_alt4.res
tests/sav/error_expr_not_ok_alt5.res
tests/sav/error_expr_not_ok_alt6.res

index 7d36d56..9b7ad1c 100644 (file)
@@ -593,7 +593,7 @@ class NeoNode
                var edges = new List[NeoEdge]
                var res = neo.get("{url.to_s}/relationships/in").as(JsonArray)
                for obj in res do
-                       edges.add(new NeoEdge.from_json(neo.as(not null), obj.as(JsonObject)))
+                       edges.add(new NeoEdge.from_json(neo, obj.as(JsonObject)))
                end
                internal_in_edges = edges
                return edges
@@ -673,7 +673,7 @@ class NeoEdge
 
        redef init from_neo(neo, url) do
                super
-               var obj = neo.get(url.as(not null)).as(JsonObject)
+               var obj = neo.get(url).as(JsonObject)
                self.internal_type = obj["type"].to_s
                self.internal_from_url = obj["start"].to_s
                self.internal_to_url = obj["end"].to_s
index 3e0e0e0..d1320a4 100644 (file)
@@ -185,7 +185,7 @@ class OptionEnum
        redef fun pretty_default
        do
                if default_value != null then
-                       return " ({values[default_value.as(not null)]})"
+                       return " ({values[default_value]})"
                else
                        return ""
                end
index c58b012..c17e9bd 100644 (file)
@@ -203,7 +203,7 @@ abstract class Rope
                                return new Path(root.as(Leaf), length, st)
                        end
                end
-               return get_node_from(root.as(not null), 0, position, new List[PathElement])
+               return get_node_from(root, 0, position, new List[PathElement])
        end
 
        # Special case for when the required pos is length
index 8a26d1e..1296ddb 100644 (file)
@@ -2545,6 +2545,8 @@ redef class AAsNotnullExpr
                var i = v.expr(self.n_expr, null)
                if v.compiler.modelbuilder.toolcontext.opt_no_check_assert.value then return i
 
+               if i.mtype.ctype != "val*" then return i
+
                v.add("if (unlikely({i} == NULL)) \{")
                v.add_abort("Cast failed")
                v.add("\}")
@@ -2582,7 +2584,7 @@ redef class ASendExpr
        do
                var recv = v.expr(self.n_expr, null)
                var args = [recv]
-               for a in self.raw_arguments.as(not null) do
+               for a in self.raw_arguments do
                        args.add(v.expr(a, null))
                end
                return v.compile_callsite(self.callsite.as(not null), args)
@@ -2594,7 +2596,7 @@ redef class ASendReassignFormExpr
        do
                var recv = v.expr(self.n_expr, null)
                var args = [recv]
-               for a in self.raw_arguments.as(not null) do
+               for a in self.raw_arguments do
                        args.add(v.expr(a, null))
                end
                var value = v.expr(self.n_value, null)
index 65b1a22..4e4402c 100644 (file)
@@ -41,7 +41,7 @@ class CLanguage
 
        redef fun compile_extern_method(block, m, ecc, mmodule)
        do
-               var fc = new ExternCFunction(m, mmodule.as(not null))
+               var fc = new ExternCFunction(m, mmodule)
                fc.decls.add( block.location.as_line_pragma )
                fc.exprs.add( block.code )
                ecc.add_exported_function( fc )
index 06d243c..938a3a0 100644 (file)
@@ -968,7 +968,7 @@ redef class ATypePropdef
                var bound = self.mpropdef.bound
                if bound == null then return # Error thus skiped
 
-               modelbuilder.check_visibility(n_type.as(not null), bound, mpropdef)
+               modelbuilder.check_visibility(n_type, bound, mpropdef)
 
                # Fast case: the bound is not a formal type
                if not bound isa MVirtualType then return
index a579aa2..9e0e14a 100644 (file)
@@ -1521,7 +1521,7 @@ redef class ASendExpr
                var recv = v.expr(self.n_expr)
                if recv == null then return null
                var args = [recv]
-               for a in self.raw_arguments.as(not null) do
+               for a in self.raw_arguments do
                        var i = v.expr(a)
                        if i == null then return null
                        args.add(i)
@@ -1538,7 +1538,7 @@ redef class ASendReassignFormExpr
                var recv = v.expr(self.n_expr)
                if recv == null then return
                var args = [recv]
-               for a in self.raw_arguments.as(not null) do
+               for a in self.raw_arguments do
                        var i = v.expr(a)
                        if i == null then return
                        args.add(i)
index dc48db8..2481ce8 100644 (file)
@@ -35,7 +35,7 @@ toolcontext.process_options(args)
 # We need a model to collect stufs
 var model = new Model
 # An a model builder to parse files
-var modelbuilder = new ModelBuilder(model, toolcontext.as(not null))
+var modelbuilder = new ModelBuilder(model, toolcontext)
 
 var arguments = toolcontext.option_context.rest
 var progname = arguments.first
@@ -57,8 +57,8 @@ else
        mainmodule.set_imported_mmodules(mmodules)
 end
 
-var self_mm = mainmodule.as(not null)
-var self_args = arguments.as(not null)
+var self_mm = mainmodule
+var self_args = arguments
 
 if toolcontext.opt_debugger_autorun.value then
        modelbuilder.run_debugger_autorun(self_mm, self_args)
index 9a62208..c0887db 100644 (file)
@@ -34,7 +34,7 @@ toolcontext.process_options(args)
 var model = new Model
 
 # Add a model builder to parse files
-var modelbuilder = new ModelBuilder(model, toolcontext.as(not null))
+var modelbuilder = new ModelBuilder(model, toolcontext)
 
 var arguments = toolcontext.option_context.rest
 var progname = arguments.first
@@ -56,7 +56,7 @@ else
        mainmodule.set_imported_mmodules(mmodules)
 end
 
-var self_mm = mainmodule.as(not null)
-var self_args = arguments.as(not null)
+var self_mm = mainmodule
+var self_args = arguments
 
 modelbuilder.run_naive_interpreter(self_mm, self_args)
index 6bd37b0..5395559 100644 (file)
@@ -226,7 +226,7 @@ redef class ASendReassignFormExpr
 
                var read_args = new Array[AExpr]
                var write_args = new Array[AExpr]
-               for a in raw_arguments.as(not null) do
+               for a in raw_arguments do
                        nblock.add(a)
                        read_args.add(a.make_var_read)
                        write_args.add(a.make_var_read)
index ccd77e2..2a21437 100644 (file)
@@ -1194,6 +1194,8 @@ redef class AAsNotnullExpr
        redef fun accept_typing(v)
        do
                var mtype = v.visit_expr(self.n_expr)
+               if mtype == null then return # Forward error
+
                if mtype isa MNullType then
                        v.error(self, "Type error: as(not null) on null")
                        return
@@ -1202,8 +1204,18 @@ redef class AAsNotnullExpr
                        self.mtype = mtype.mtype
                        return
                end
-               # TODO: warn on useless as not null
                self.mtype = mtype
+
+               if mtype isa MClassType then
+                       v.modelbuilder.warning(self, "Warning: expression is already not null, since it is a `{mtype}`.")
+                       return
+               end
+               assert mtype.need_anchor
+               var u = v.anchor_to(mtype)
+               if not u isa MNullableType then
+                       v.modelbuilder.warning(self, "Warning: expression is already not null, since it is a `{mtype}: {u}`.")
+                       return
+               end
        end
 end
 
diff --git a/tests/base_as_notnull2.nit b/tests/base_as_notnull2.nit
new file mode 100644 (file)
index 0000000..d9ad95c
--- /dev/null
@@ -0,0 +1,64 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class G[E]
+       fun foo(e: E): E
+       do
+               var ee = e.as(not null)
+               ee.output
+               return ee
+       end
+end
+
+class A
+       super G[Object]
+       redef fun foo(e)
+       do
+               var ee = e.as(not null)
+               ee.output
+               return ee
+       end
+end
+
+class B[F: Object]
+       super G[nullable F]
+       redef fun foo(e)
+       do
+               var ee = e.as(not null)
+               ee.output
+               return ee
+       end
+end
+
+class C[F: Object]
+       super G[F]
+       redef fun foo(e)
+       do
+               var ee = e.as(not null)
+               ee.output
+               return ee
+       end
+end
+
+var a = new A
+a.foo(1).output
+#alt1#a.foo(null).output
+var b = new B[Int]
+b.foo(2).output
+#alt2#b.foo(null).output
+var c = new C[Int]
+c.foo(3).output
+#alt3#c.foo(null).output
diff --git a/tests/base_as_notnull_int.nit b/tests/base_as_notnull_int.nit
new file mode 100644 (file)
index 0000000..0b19e6e
--- /dev/null
@@ -0,0 +1,23 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+var i: Int = 1
+i.as(not null).output
+var oi: Object = i
+oi.as(not null).output
+var ni: nullable Int = i
+ni.as(not null).output
+
index 8f499ee..2380a43 100644 (file)
@@ -1,3 +1,7 @@
+base_as_notnull.nit:41,6--19: Warning: expression is already not null, since it is a `A`.
+base_as_notnull.nit:42,6--20: Warning: expression is already not null, since it is a `A`.
+base_as_notnull.nit:43,6--19: Warning: expression is already not null, since it is a `B`.
+base_as_notnull.nit:52,6--19: Warning: expression is already not null, since it is a `B`.
 1
 2
 3
diff --git a/tests/sav/base_as_notnull2.res b/tests/sav/base_as_notnull2.res
new file mode 100644 (file)
index 0000000..c426288
--- /dev/null
@@ -0,0 +1,8 @@
+base_as_notnull2.nit:30,12--25: Warning: expression is already not null, since it is a `G#0: Object`.
+base_as_notnull2.nit:50,12--25: Warning: expression is already not null, since it is a `G#0: Object`.
+1
+1
+2
+2
+3
+3
diff --git a/tests/sav/base_as_notnull2_alt1.res b/tests/sav/base_as_notnull2_alt1.res
new file mode 100644 (file)
index 0000000..e6b980e
--- /dev/null
@@ -0,0 +1,3 @@
+alt/base_as_notnull2_alt1.nit:30,12--25: Warning: expression is already not null, since it is a `G#0: Object`.
+alt/base_as_notnull2_alt1.nit:50,12--25: Warning: expression is already not null, since it is a `G#0: Object`.
+alt/base_as_notnull2_alt1.nit:58,7--10: Type error: expected Object, got null
diff --git a/tests/sav/base_as_notnull2_alt2.res b/tests/sav/base_as_notnull2_alt2.res
new file mode 100644 (file)
index 0000000..0d136a8
--- /dev/null
@@ -0,0 +1,7 @@
+alt/base_as_notnull2_alt2.nit:30,12--25: Warning: expression is already not null, since it is a `G#0: Object`.
+alt/base_as_notnull2_alt2.nit:50,12--25: Warning: expression is already not null, since it is a `G#0: Object`.
+Runtime error: Cast failed (alt/base_as_notnull2_alt2.nit:40)
+1
+1
+2
+2
diff --git a/tests/sav/base_as_notnull2_alt3.res b/tests/sav/base_as_notnull2_alt3.res
new file mode 100644 (file)
index 0000000..c166c42
--- /dev/null
@@ -0,0 +1,3 @@
+alt/base_as_notnull2_alt3.nit:30,12--25: Warning: expression is already not null, since it is a `G#0: Object`.
+alt/base_as_notnull2_alt3.nit:50,12--25: Warning: expression is already not null, since it is a `G#0: Object`.
+alt/base_as_notnull2_alt3.nit:64,7--10: Type error: expected Int, got null
index 60b7d08..ad6b798 100644 (file)
@@ -1 +1,6 @@
+alt/base_as_notnull_alt1.nit:41,6--19: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt1.nit:42,6--20: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt1.nit:43,6--19: Warning: expression is already not null, since it is a `B`.
+alt/base_as_notnull_alt1.nit:50,6--19: Warning: expression is already not null, since it is a `A`.
 alt/base_as_notnull_alt1.nit:50,6--19: Type error: expected B, got A
+alt/base_as_notnull_alt1.nit:52,6--19: Warning: expression is already not null, since it is a `B`.
index c076807..0e0e68c 100644 (file)
@@ -1 +1,6 @@
+alt/base_as_notnull_alt2.nit:41,6--19: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt2.nit:42,6--20: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt2.nit:43,6--19: Warning: expression is already not null, since it is a `B`.
+alt/base_as_notnull_alt2.nit:51,6--20: Warning: expression is already not null, since it is a `A`.
 alt/base_as_notnull_alt2.nit:51,6--20: Type error: expected B, got A
+alt/base_as_notnull_alt2.nit:52,6--19: Warning: expression is already not null, since it is a `B`.
index a88beb6..bd83530 100644 (file)
@@ -1 +1,5 @@
+alt/base_as_notnull_alt3.nit:41,6--19: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt3.nit:42,6--20: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt3.nit:43,6--19: Warning: expression is already not null, since it is a `B`.
+alt/base_as_notnull_alt3.nit:52,6--19: Warning: expression is already not null, since it is a `B`.
 alt/base_as_notnull_alt3.nit:53,6--20: Type error: expected B, got A
index ff16195..0050108 100644 (file)
@@ -1 +1,5 @@
+alt/base_as_notnull_alt4.nit:41,6--19: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt4.nit:42,6--20: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt4.nit:43,6--19: Warning: expression is already not null, since it is a `B`.
+alt/base_as_notnull_alt4.nit:52,6--19: Warning: expression is already not null, since it is a `B`.
 alt/base_as_notnull_alt4.nit:54,6--21: Type error: expected B, got A
index 917dafb..d8136e9 100644 (file)
@@ -1,3 +1,7 @@
+alt/base_as_notnull_alt5.nit:41,6--19: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt5.nit:42,6--20: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt5.nit:43,6--19: Warning: expression is already not null, since it is a `B`.
+alt/base_as_notnull_alt5.nit:52,6--19: Warning: expression is already not null, since it is a `B`.
 Runtime error: Cast failed (alt/base_as_notnull_alt5.nit:59)
 1
 2
index 49784b7..7083fa3 100644 (file)
@@ -1,3 +1,7 @@
+alt/base_as_notnull_alt6.nit:41,6--19: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt6.nit:42,6--20: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt6.nit:43,6--19: Warning: expression is already not null, since it is a `B`.
+alt/base_as_notnull_alt6.nit:52,6--19: Warning: expression is already not null, since it is a `B`.
 Runtime error: Cast failed (alt/base_as_notnull_alt6.nit:60)
 1
 2
index 0419b7f..38f0903 100644 (file)
@@ -1 +1,5 @@
+alt/base_as_notnull_alt7.nit:41,6--19: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt7.nit:42,6--20: Warning: expression is already not null, since it is a `A`.
+alt/base_as_notnull_alt7.nit:43,6--19: Warning: expression is already not null, since it is a `B`.
+alt/base_as_notnull_alt7.nit:52,6--19: Warning: expression is already not null, since it is a `B`.
 alt/base_as_notnull_alt7.nit:61,1--17: Type error: as(not null) on null
diff --git a/tests/sav/base_as_notnull_int.res b/tests/sav/base_as_notnull_int.res
new file mode 100644 (file)
index 0000000..4635340
--- /dev/null
@@ -0,0 +1,5 @@
+base_as_notnull_int.nit:18,1--14: Warning: expression is already not null, since it is a `Int`.
+base_as_notnull_int.nit:20,1--15: Warning: expression is already not null, since it is a `Object`.
+1
+1
+1
index ad06d43..0e3f1e5 100644 (file)
@@ -106,6 +106,7 @@ alt/error_expr_not_ok_alt4.nit:147,7--18: Type error: expected A, got Array[Int]
 alt/error_expr_not_ok_alt4.nit:149,7--24: Type error: expected A, got String
 alt/error_expr_not_ok_alt4.nit:150,7--18: Warning: Expression is already a Int.
 alt/error_expr_not_ok_alt4.nit:150,7--18: Type error: expected A, got Int
+alt/error_expr_not_ok_alt4.nit:151,7--23: Warning: expression is already not null, since it is a `Int`.
 alt/error_expr_not_ok_alt4.nit:151,7--23: Type error: expected A, got Int
 alt/error_expr_not_ok_alt4.nit:152,7--18: Warning: Expression is already a Int.
 alt/error_expr_not_ok_alt4.nit:152,7--18: Type error: expected A, got Bool
index 5a9cc45..b85ac5b 100644 (file)
@@ -101,6 +101,7 @@ alt/error_expr_not_ok_alt5.nit:147,7--18: Type error: expected A, got Array[Int]
 alt/error_expr_not_ok_alt5.nit:149,7--24: Type error: expected A, got String
 alt/error_expr_not_ok_alt5.nit:150,7--18: Warning: Expression is already a Int.
 alt/error_expr_not_ok_alt5.nit:150,7--18: Type error: expected A, got Int
+alt/error_expr_not_ok_alt5.nit:151,7--23: Warning: expression is already not null, since it is a `Int`.
 alt/error_expr_not_ok_alt5.nit:151,7--23: Type error: expected A, got Int
 alt/error_expr_not_ok_alt5.nit:152,7--18: Warning: Expression is already a Int.
 alt/error_expr_not_ok_alt5.nit:152,7--18: Type error: expected A, got Bool
index 3d37819..039e32d 100644 (file)
@@ -105,6 +105,7 @@ alt/error_expr_not_ok_alt6.nit:147,7--18: Type error: expected A, got Array[Int]
 alt/error_expr_not_ok_alt6.nit:149,7--24: Type error: expected A, got String
 alt/error_expr_not_ok_alt6.nit:150,7--18: Warning: Expression is already a Int.
 alt/error_expr_not_ok_alt6.nit:150,7--18: Type error: expected A, got Int
+alt/error_expr_not_ok_alt6.nit:151,7--23: Warning: expression is already not null, since it is a `Int`.
 alt/error_expr_not_ok_alt6.nit:151,7--23: Type error: expected A, got Int
 alt/error_expr_not_ok_alt6.nit:152,7--18: Warning: Expression is already a Int.
 alt/error_expr_not_ok_alt6.nit:152,7--18: Type error: expected A, got Bool