typing: include a hook to enable more precise error information on 'expected expressi...
authorJean Privat <jean@pryen.org>
Thu, 25 Feb 2016 19:11:57 +0000 (14:11 -0500)
committerJean Privat <jean@pryen.org>
Thu, 25 Feb 2016 23:29:07 +0000 (18:29 -0500)
Signed-off-by: Jean Privat <jean@pryen.org>

src/semantize/typing.nit
tests/error_arg.nit [new file with mode: 0644]
tests/sav/base_meth_call_alt1.res
tests/sav/error_arg.res [new file with mode: 0644]
tests/sav/error_arg_alt1.res [new file with mode: 0644]

index aeb3b7e..ddc87e2 100644 (file)
@@ -152,7 +152,11 @@ private class TypeVisitor
                        end
                        return null # forward error
                end
-               self.error(nexpr, "Error: expected an expression.")
+               var more_message = null
+               var p = nexpr.parent
+               if p != null then more_message = p.bad_expr_message(nexpr)
+               if more_message == null then more_message = "" else more_message = " " + more_message
+               self.error(nexpr, "Error: expected an expression{more_message}.")
                return null
        end
 
@@ -802,6 +806,12 @@ end
 
 redef class ANode
        private fun accept_post_typing(v: TypeVisitor) do end
+
+       # An additional information message to explain the role of a child expression.
+       #
+       # The point of the method is to allow some kind of double dispatch so the parent
+       # choose how to describe its children.
+       private fun bad_expr_message(child: AExpr): nullable String do return null
 end
 
 redef class AAttrPropdef
@@ -1710,6 +1720,14 @@ redef class ASendExpr
        # The property invoked by the send.
        var callsite: nullable CallSite
 
+       redef fun bad_expr_message(child)
+       do
+               if child == self.n_expr then
+                       return "to be the receiver of `{self.property_name}`"
+               end
+               return null
+       end
+
        redef fun accept_typing(v)
        do
                var nrecv = self.n_expr
diff --git a/tests/error_arg.nit b/tests/error_arg.nit
new file mode 100644 (file)
index 0000000..c550d9f
--- /dev/null
@@ -0,0 +1,39 @@
+# 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 core::kernel
+
+redef class Int
+       fun a: Int do return 10*self+self.abs
+end
+
+fun foo(a: Int): Int do
+       a.output
+       return a
+end
+fun bar(a: Int) do a.output
+
+foo 1.a
+foo(1.a)
+foo (1).a
+foo(1).a
+foo((1).a)
+
+'\n'.output
+
+bar 1.a
+bar(1.a)
+#alt1#bar (1).a
+#alt1#bar(1).a
+bar((1).a)
index 5b14b4e..b2c999e 100644 (file)
@@ -1 +1 @@
-alt/base_meth_call_alt1.nit:36,1--6: Error: expected an expression.
+alt/base_meth_call_alt1.nit:36,1--6: Error: expected an expression to be the receiver of `output`.
diff --git a/tests/sav/error_arg.res b/tests/sav/error_arg.res
new file mode 100644 (file)
index 0000000..1aa7d08
--- /dev/null
@@ -0,0 +1,9 @@
+11
+11
+1
+1
+11
+
+11
+11
+11
diff --git a/tests/sav/error_arg_alt1.res b/tests/sav/error_arg_alt1.res
new file mode 100644 (file)
index 0000000..efe82e4
--- /dev/null
@@ -0,0 +1,2 @@
+alt/error_arg_alt1.nit:37,1--7: Error: expected an expression to be the receiver of `a`.
+alt/error_arg_alt1.nit:38,1--6: Error: expected an expression to be the receiver of `a`.