syntax: better message for signature errors
authorJean Privat <jean@pryen.org>
Fri, 29 Apr 2011 23:54:10 +0000 (19:54 -0400)
committerJean Privat <jean@pryen.org>
Thu, 23 Jun 2011 16:29:53 +0000 (12:29 -0400)
Locate the error on the erroneous parameter or return type.

Signed-off-by: Jean Privat <jean@pryen.org>

14 files changed:
src/syntax/mmbuilder.nit
tests/base_attr7.nit [new file with mode: 0644]
tests/sav/base_attr7.sav [new file with mode: 0644]
tests/sav/base_attr7_alt1.sav [new file with mode: 0644]
tests/sav/base_attr7_alt2.sav [new file with mode: 0644]
tests/sav/base_attr7_alt3.sav [new file with mode: 0644]
tests/sav/error_ref_attr.sav
tests/sav/error_ref_param.sav
tests/sav/error_ref_ret.sav
tests/sav/error_spe_attr.sav
tests/sav/error_spe_param.sav
tests/sav/error_spe_param2.sav
tests/sav/error_spe_ret.sav
tests/sav/test_multiconstraint_inh.sav

index 1fd92f3..0c41698 100644 (file)
@@ -892,11 +892,22 @@ redef class APropdef
 
                        if s.arity != isig.arity then
                                v.error(self, "Redef error: {prop.local_class}::{prop} redefines {ip.local_class}::{ip} with {isig.arity} parameter(s).")
-                       else
-                               for j in [0..s.arity[ do
-                                       if s[j] != isig[j] then
-                                               v.error(self, "Redef error: Expected {isig[j]} (as in {ip.local_class}::{ip}), got {s[j]} in {prop.local_class}::{prop}.")
+                       else if s.arity > 0 then
+                               if self isa AMethPropdef then
+                                       # A standard method
+                                       for j in [0..s.arity[ do
+                                               if s[j] != isig[j] then
+                                                       v.error(n_signature.n_params[j], "Redef error: Expected {isig[j]}, as in {ip.local_class}::{ip}.")
+                                               end
+                                       end
+                               else if self isa AAttrPropdef then
+                                       # A write accessor
+                                       if s[0] != isig[0] then
+                                               v.error(n_type, "Redef error: Expected {isig[0]}, as in the parameter of {ip.local_class}::{ip}.")
                                        end
+
+                               else
+                                       abort #
                                end
                        end
 
@@ -907,13 +918,21 @@ redef class APropdef
                        else if srt != null and isrt == null then
                                v.error(self, "Redef error: The function {prop.local_class}::{prop} redefines the procedure {ip.local_class}::{ip}.")
                        else if srt != null and isrt != null and not srt < isrt then
-                               v.error(self, "Redef error: Expected {isrt} (as in {ip.local_class}::{ip}), got {srt} in {prop.local_class}::{prop}.")
+                               var n: nullable ANode = null
+                               if self isa AMethPropdef then
+                                       n = self.n_signature.n_type
+                               else if self isa AAttrPropdef then
+                                       n = self.n_type
+                               else if self isa ATypePropdef then
+                                       n = self.n_type
+                               end
+                               v.error(n, "Redef error: Expected {isrt}, as in {ip.local_class}::{ip}.")
                        else if not s < isig and nberr == v.tc.error_count then
                                # Systematic fallback for conformance check
                                v.error(self, "Redef error: Incompatible redefinition of {ip.local_class}::{ip} with {prop.local_class}::{prop}")
                        else if srt != null and isrt != null and srt != isrt and prop isa MMAttribute then
                                # FIXME: To remove
-                               v.warning(self, "Redef warning: Expected {isrt} (as in {ip.local_class}::{ip}), got {srt} in {prop.local_class}::{prop}.")
+                               v.warning(self, "Redef warning: Expected {isrt}, as in {ip.local_class}::{ip}.")
                        end
                end
 
diff --git a/tests/base_attr7.nit b/tests/base_attr7.nit
new file mode 100644 (file)
index 0000000..c3605cc
--- /dev/null
@@ -0,0 +1,46 @@
+# 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 A
+       fun foo: Int do return 1
+       fun bar=(i: Int)
+       do
+               '#'.output
+               i.output
+       end
+       fun baz: Int do return 3
+       fun baz=(i: Int)
+       do
+               '#'.output
+               i.output
+       end
+end
+
+class B
+       super A
+       #alt1#redef var foo: Bool = true
+       #alt2#var bar: Bool redef writable = true
+       #alt3#redef var baz: Bool redef writable = true
+end
+
+var b = new B
+b.foo.output
+'\n'.output
+b.bar = 200
+'\n'.output
+b.baz.output
+b.baz = 300
+b.baz.output
diff --git a/tests/sav/base_attr7.sav b/tests/sav/base_attr7.sav
new file mode 100644 (file)
index 0000000..6744b71
--- /dev/null
@@ -0,0 +1,7 @@
+1
+
+#200
+
+3
+#300
+3
diff --git a/tests/sav/base_attr7_alt1.sav b/tests/sav/base_attr7_alt1.sav
new file mode 100644 (file)
index 0000000..24902c1
--- /dev/null
@@ -0,0 +1 @@
+alt/base_attr7_alt1.nit:34,17--20: Redef error: Expected Int, as in A::foo.
diff --git a/tests/sav/base_attr7_alt2.sav b/tests/sav/base_attr7_alt2.sav
new file mode 100644 (file)
index 0000000..2253530
--- /dev/null
@@ -0,0 +1 @@
+alt/base_attr7_alt2.nit:35,11--14: Redef error: Expected Int, as in the parameter of A::bar=.
diff --git a/tests/sav/base_attr7_alt3.sav b/tests/sav/base_attr7_alt3.sav
new file mode 100644 (file)
index 0000000..ac94207
--- /dev/null
@@ -0,0 +1,2 @@
+alt/base_attr7_alt3.nit:36,17--20: Redef error: Expected Int, as in A::baz.
+alt/base_attr7_alt3.nit:36,17--20: Redef error: Expected Int, as in the parameter of A::baz=.
index f4d8101..94b256c 100644 (file)
@@ -1 +1 @@
-./error_ref_attr.nit:20,2--18: Redef error: Expected B (as in C::_a), got Int in C::_a.
+./error_ref_attr.nit:20,16--18: Redef error: Expected B, as in C::_a.
index 08bbdf4..1fb38d8 100644 (file)
@@ -1 +1 @@
-./error_ref_param.nit:20,2--17: Redef error: Expected B (as in C::r), got C in C::r.
+./error_ref_param.nit:20,14--17: Redef error: Expected B, as in C::r.
index 6d83b27..d728031 100644 (file)
@@ -1 +1 @@
-./error_ref_ret.nit:20,2--29: Redef error: Expected B (as in C::s), got Int in C::s.
+./error_ref_ret.nit:20,15--17: Redef error: Expected B, as in C::s.
index b518ad1..eb2380e 100644 (file)
@@ -1 +1 @@
-./error_spe_attr.nit:22,2--21: Redef error: Expected Int (as in A::_a), got Object in B::_a.
+./error_spe_attr.nit:22,16--21: Redef error: Expected Int, as in A::_a.
index 32f94b5..c1efaa0 100644 (file)
@@ -1 +1 @@
-./error_spe_param.nit:24,1--24: Redef error: Expected Int (as in A::toto), got Object in B::toto.
+./error_spe_param.nit:24,16--24: Redef error: Expected Int, as in A::toto.
index 39a8177..1ee9ee3 100644 (file)
@@ -1 +1 @@
-./error_spe_param2.nit:24,1--22: Redef error: Expected Int (as in A::toto), got Char in B::toto.
+./error_spe_param2.nit:24,16--22: Redef error: Expected Int, as in A::toto.
index c249b92..909078b 100644 (file)
@@ -1 +1 @@
-./error_spe_ret.nit:23,1--34: Redef error: Expected Int (as in A::toto), got Char in B::toto.
+./error_spe_ret.nit:23,17--20: Redef error: Expected Int, as in A::toto.
index 35efa63..ca6262c 100644 (file)
@@ -1 +1 @@
-./test_multiconstraint_inh.nit:39,4--31: Redef error: Expected I[A] (as in G::baz), got J in H::baz.
+./test_multiconstraint_inh.nit:39,18--21: Redef error: Expected I[A], as in G::baz.