From 58c34d72fa3a10a13016ca8fdf241b14a0ef1de6 Mon Sep 17 00:00:00 2001 From: Florian Deljarry Date: Mon, 11 Jun 2018 16:10:45 -0400 Subject: [PATCH 1/7] =?UTF-8?q?Adding=20=E2=80=98inspect=5Fo=E2=80=99=20fu?= =?UTF-8?q?ntion=20This=20method=20is=20catch=20by=20the=20interpreter=20t?= =?UTF-8?q?o=20display=20the=20object=20value=20and=20to=20start=20the=20s?= =?UTF-8?q?tep-by-step=20execution.=20This=20method=20MUST=20not=20be=20us?= =?UTF-8?q?ed=20by=20programs,=20it=20is=20here=20for=20debugging=20in=20t?= =?UTF-8?q?he=20interpreter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Deljarry --- lib/core/kernel.nit | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/core/kernel.nit b/lib/core/kernel.nit index 45c3ccd100..cf0ac98f4e 100644 --- a/lib/core/kernel.nit +++ b/lib/core/kernel.nit @@ -222,6 +222,11 @@ interface Object # # Without redefinition, `hash` is based on the `object_id` of the instance. fun hash: Int do return object_id + + # Method catch by the interpreter to display the object value and to start the step-by-step execution. + # + # This method MUST not be used by programs, it is here for debugging in the interpreter + fun inspect_o is intern end # The main class of the program. From d3ac2efa2019143ec4c4cd306587bfdfa8f92533 Mon Sep 17 00:00:00 2001 From: Florian Deljarry Date: Mon, 11 Jun 2018 16:22:31 -0400 Subject: [PATCH 2/7] Adding object inspection method to the naive_interpreter Add : - Class ObjectInspected to represent the inspected object - Class ObjectInspector to provide the inspect_object method that will return the inspect object as a tree (OrderedTree[ObjectInspected]) Signed-off-by: Florian Deljarry --- src/interpreter/step_interpreter.nit | 92 ++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/interpreter/step_interpreter.nit diff --git a/src/interpreter/step_interpreter.nit b/src/interpreter/step_interpreter.nit new file mode 100644 index 0000000000..c26444b850 --- /dev/null +++ b/src/interpreter/step_interpreter.nit @@ -0,0 +1,92 @@ +# 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. + +# Interpretation of a Nit program directly on the AST +module step_interpreter + +intrude import naive_interpreter +import ordered_tree +import highlight + +# Represents the inspected object with the relationship between the instance and the name of the object (if it exists) +class ObjectInspected + # The instance of the inspected object. + var instance : Instance + # The name of the inspected object (if does not exist = null) + var name : nullable String + + redef fun to_s do + var return_value = "Class type '{instance.mtype.name.green}'" + var n = name + if n != null then + if instance isa PrimitiveInstance[Object] and not instance isa PrimitiveInstance[Array[Object]] then + return_value += " : Name '{n}' : Value = {instance.val.to_s.purple}" + else + return_value += " : Name '{n}'" + end + end + return return_value + end +end + +class ObjectInspector + + # Execute the object inspection. + # Return a OrderedTree[ObjectInspected] that represents the hierarchy of the inspected object + fun inspect_object(recv: Instance, tree : OrderedTree[ObjectInspected], old : nullable ObjectInspected, visited_instance : List[Instance]):OrderedTree[ObjectInspected] do + # check if the instance has already visited + if not visited_instance.has(recv) then + visited_instance.add(recv) + # check Instance type + if recv isa PrimitiveInstance[Object] then + # check if the instance visited is the first Instance + if visited_instance.length == 1 then + tree.add(null,new ObjectInspected(recv,old.name)) + else + # add an ObjectInspected leaf to the previous node + tree.add(old,new ObjectInspected(recv,old.name)) + end + else if recv isa MutableInstance then + # unstack attributes list + for mattribute, instance in recv.attributes do + # create new Object with the mattribute and the associated instance + var debug = new ObjectInspected(instance,mattribute.name) + # add an ObjectInspected leaf to the previous node + tree.add(old,debug) + # check if the type of the instance is a primitive type + if instance isa PrimitiveInstance[Object] then + # this check is for the primitive type Array + if instance isa PrimitiveInstance[Array[Object]] then + # get array values and unstack this to re execute the inspection method + for ins in instance.val do + # check the instance type + if ins isa MutableInstance then + old = new ObjectInspected(ins,null) + tree.add(debug,old) + tree = inspect_object(ins,tree,old,visited_instance) + else + tree = inspect_object(ins.as(Instance),tree,debug,visited_instance) + end + end + end + else + # execute recursively inspection method + tree = inspect_object(instance,tree,debug,visited_instance) + end + end + end + end + return tree + end +end From b803ed41f03d25cca75d78fc0176b82239997c2d Mon Sep 17 00:00:00 2001 From: Florian Deljarry Date: Mon, 11 Jun 2018 16:40:04 -0400 Subject: [PATCH 3/7] Add interception of the method inspect_o and step-by-step execution Add : -The step-by-step execution in naive_interpreter -Print the inspected object Signed-off-by: Florian Deljarry --- src/interpreter/step_interpreter.nit | 118 +++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/src/interpreter/step_interpreter.nit b/src/interpreter/step_interpreter.nit index c26444b850..0aa1bafc9f 100644 --- a/src/interpreter/step_interpreter.nit +++ b/src/interpreter/step_interpreter.nit @@ -19,6 +19,111 @@ intrude import naive_interpreter import ordered_tree import highlight +# The visitor that interprets the Nit Program by walking on the AST +redef class NaiveInterpreter + + # The deep of the frames + # This information is stored to check if the step-into mode is returned to the call method + var deep_old_frame = 0 + + # The old line number + # This information is stored to check if the instruction have change line + var old_line_number = 0 + + # The object provide the inspector object method + var object_inspector = new ObjectInspector + + # This flag is used to launch setp by step interpreter + var debug_flag = false + + private var user_entry = "" + + # Print the commands to execute step-by-step execution + fun print_instruction_debug do + print "────────────────────────────────────────────────────────────────────" + print "∣You enter in the step-by-step mode" + print "∣Enter " + "'step'".yellow + " to do a step-into" + print "∣Press " + "'enter'".yellow + " to do a step-over" + print "∣Enter something else to exit the step-by-step mode" + print "────────────────────────────────────────────────────────────────────" + end + + # Return the colored line of the current node + fun get_color_line: String + do + var highlight = new AnsiHighlightVisitor + var node = current_node + if node != null then + highlight.include_whole_lines = true + highlight.first_line = node.hot_location.line_start + highlight.last_line = node.hot_location.line_start + highlight.highlight_node(node) + return "{node.hot_location.line_start}|{highlight.result.write_to_string.replace("\t","")}" + end + return "" + end + + # Method used when intercepting the method inspect_o + fun inspect_object(instance: Instance) do + print "{object_inspector.inspect_object(instance,new OrderedTree[ObjectInspected],new ObjectInspected(instance,variable.name),new List[Instance])}" + init_debug_mode + deep_old_frame = frames.length + self.debug_flag = true + end + + # Init step-by-step mode + fun init_debug_mode do + if deep_old_frame == 0 then + deep_old_frame = frames.length + print_instruction_debug + end + end + + # Main function of the step-by-step execution this method is called after each instruction + fun step_execution(recv : nullable Instance) do + if self.debug_flag then + init_debug_mode + if user_entry == "" or user_entry == "next" then + self.step_over + else if user_entry == "step" then + self.step_into + else + self.debug_flag = false + end + end + end + + fun step_into do + print "{self.get_color_line}" + deep_old_frame = frames.length + user_entry = stdin.read_line + old_line_number = frame.current_node.location.line_start + end + + fun step_over do + # Check if the new instruction is in the same method or the new instruction is in the appellant method + # Check the line to execute all instruction line + if frames.length <= deep_old_frame and old_line_number != frame.current_node.location.line_start then + self.step_into + end + end + + redef fun expr(n: AExpr): nullable Instance + do + var i = super + if i != null then step_execution(i) + return i + end + + redef fun stmt(n) + do + if n != null then + step_execution + frame.current_node = n + end + super + end +end # Represents the inspected object with the relationship between the instance and the name of the object (if it exists) class ObjectInspected # The instance of the inspected object. @@ -90,3 +195,16 @@ class ObjectInspector return tree end end + +redef class AMethPropdef + redef fun intern_call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance + do + var pname = mpropdef.mproperty.name + if pname == "inspect_o" then + var recv = args.first + v.inspect_object(recv) + return null + end + return super + end +end From 44417e9a9ff642d3352bbe30d3e7ab9a7e0e93c4 Mon Sep 17 00:00:00 2001 From: Florian Deljarry Date: Tue, 12 Jun 2018 09:20:27 -0400 Subject: [PATCH 4/7] Adding watch list refresh to naive_interpreter Signed-off-by: Florian Deljarry --- src/interpreter/step_interpreter.nit | 97 +++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/src/interpreter/step_interpreter.nit b/src/interpreter/step_interpreter.nit index 0aa1bafc9f..d2e6d27d08 100644 --- a/src/interpreter/step_interpreter.nit +++ b/src/interpreter/step_interpreter.nit @@ -44,6 +44,7 @@ redef class NaiveInterpreter print "∣You enter in the step-by-step mode" print "∣Enter " + "'step'".yellow + " to do a step-into" print "∣Press " + "'enter'".yellow + " to do a step-over" + print "∣Enter " + "'watch'".yellow + " to print the watch list variables" print "∣Enter something else to exit the step-by-step mode" print "────────────────────────────────────────────────────────────────────" end @@ -65,7 +66,8 @@ redef class NaiveInterpreter # Method used when intercepting the method inspect_o fun inspect_object(instance: Instance) do - print "{object_inspector.inspect_object(instance,new OrderedTree[ObjectInspected],new ObjectInspected(instance,variable.name),new List[Instance])}" + object_inspector.add_object_watch_list(instance) + object_inspector.mark_watch_list(instance,read_instance(instance),self) init_debug_mode deep_old_frame = frames.length self.debug_flag = true @@ -83,6 +85,9 @@ redef class NaiveInterpreter fun step_execution(recv : nullable Instance) do if self.debug_flag then init_debug_mode + if recv != null then + self.object_inspector.mark_watch_list(recv,read_instance(recv),self) + end if user_entry == "" or user_entry == "next" then self.step_over else if user_entry == "step" then @@ -147,6 +152,96 @@ end class ObjectInspector + # This HashMap is used to store the inspected objects + var object_watch_list = new HashMap[Instance,OrderedTree[ObjectInspected]] + + # This HashMap is used to store the inspected variable + var variable_watch_list = new HashMap[Variable,OrderedTree[ObjectInspected]] + + # This list contains all the instances of the same line + var mark_list = new Array[Object] + + fun print_inspected_element(tree : OrderedTree[ObjectInspected]) do + print "────────────────────────────────────────────────────────────────────" + tree.write_to(stdout) + print "────────────────────────────────────────────────────────────────────" + end + + # Display the pin values + fun print_pin_list_value do + for instance , tree in object_watch_list do + print_inspected_element(tree) + end + for instance , tree in variable_watch_list do + print_inspected_element(tree) + end + end + + # Method to add an instance in the object_watch_list + fun add_object_watch_list(instance: Instance) do + object_watch_list[instance] = inspect_object(instance,new OrderedTree[ObjectInspected],new ObjectInspected(instance,""),new List[Instance]) + end + + # Method called for each new instance visited to indicate which may have been modified + fun mark_watch_list(instance: Instance, variable : nullable Variable,v : NaiveInterpreter) do + if not instance.mtype isa MNullType then + check_refrech(v) + if not mark_list.has(variable) and variable != null then + mark_list.add(variable) + else if not mark_list.has(instance) and variable == null then + mark_list.add(instance) + end + end + end + + # Method called to verify if the line have changed + fun check_refrech(v: NaiveInterpreter)do + if v.frames.length <= v.deep_old_frame and v.old_line_number != v.frame.current_node.location.line_start then + refrech_object_watch_list(v) + end + end + + # Update the watchs list (instance and variable) + fun refrech_object_watch_list(interpreter : NaiveInterpreter) do + for item in mark_list do + if item isa Instance then + var variable = interpreter.read_instance(item) + refrech_instance_watch_list(variable,item) + else if item isa Variable then + var instance = interpreter.read_null_variable(item) + refrech_variable_watch_list(item,instance) + end + end + mark_list.clear + end + + # Update the instance watch list + fun refrech_instance_watch_list(variable : nullable Variable , instance : Instance) do + if variable != null then + refrech_variable_watch_list(variable,instance) + else if object_watch_list.has_key(instance) then + object_watch_list[instance].roots.first.name = "Return value" + print_inspected_element(object_watch_list[instance]) + self.object_watch_list.keys.remove(instance) + end + end + + # Update the variable watch list + fun refrech_variable_watch_list(variable : Variable , instance : nullable Instance) do + if variable_watch_list.has_key(variable) and instance != null then + var update = inspect_object(instance,new OrderedTree[ObjectInspected],new ObjectInspected(instance,variable.name),new List[Instance]) + if self.variable_watch_list[variable].to_s != update.to_s then + self.variable_watch_list[variable] = update + print_inspected_element(update) + end + else if object_watch_list.has_key(instance) then + object_watch_list[instance].roots.first.name = variable.name + variable_watch_list[variable] = object_watch_list[instance] + print_inspected_element(object_watch_list[instance]) + self.object_watch_list.keys.remove(instance) + end + end + # Execute the object inspection. # Return a OrderedTree[ObjectInspected] that represents the hierarchy of the inspected object fun inspect_object(recv: Instance, tree : OrderedTree[ObjectInspected], old : nullable ObjectInspected, visited_instance : List[Instance]):OrderedTree[ObjectInspected] do From b8892a6b527d7029337523769ed209d5409e7d9c Mon Sep 17 00:00:00 2001 From: Florian Deljarry Date: Tue, 12 Jun 2018 09:25:34 -0400 Subject: [PATCH 5/7] Adding step-by-step execution option Add: -'backtrace full' option to print the local variables of the method -'watch' option to print all selected values with 'object_id' -'continue' option to execute the code until the next break point 'object_id' Signed-off-by: Florian Deljarry --- src/interpreter/step_interpreter.nit | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/interpreter/step_interpreter.nit b/src/interpreter/step_interpreter.nit index d2e6d27d08..544db1ffb8 100644 --- a/src/interpreter/step_interpreter.nit +++ b/src/interpreter/step_interpreter.nit @@ -44,7 +44,9 @@ redef class NaiveInterpreter print "∣You enter in the step-by-step mode" print "∣Enter " + "'step'".yellow + " to do a step-into" print "∣Press " + "'enter'".yellow + " to do a step-over" + print "∣Enter " + "'backtrace full'".yellow + " to print the locals variables" print "∣Enter " + "'watch'".yellow + " to print the watch list variables" + print "∣Enter " + "'continue'".yellow + " to execute the code until the next breakpoint " print "∣Enter something else to exit the step-by-step mode" print "────────────────────────────────────────────────────────────────────" end @@ -92,6 +94,17 @@ redef class NaiveInterpreter self.step_over else if user_entry == "step" then self.step_into + else if user_entry == "backtrace full" then + self.object_inspector.print_all_frame_value(frame.as(InterpreterFrame)) + self.user_entry = stdin.read_line + self.step_execution(recv) + else if user_entry == "watch" then + self.object_inspector.print_pin_list_value + self.user_entry = stdin.read_line + self.step_execution(recv) + else if user_entry == "continue" then + self.user_entry = "" + self.debug_flag = false else self.debug_flag = false end @@ -167,6 +180,14 @@ class ObjectInspector print "────────────────────────────────────────────────────────────────────" end + # Display all local frames values + fun print_all_frame_value(frame : InterpreterFrame) do + for variable, instance in frame.map do + var tree = inspect_object(instance,new OrderedTree[ObjectInspected],new ObjectInspected(instance,variable.name),new List[Instance]) + print_inspected_element(tree) + end + end + # Display the pin values fun print_pin_list_value do for instance , tree in object_watch_list do From 9b5774bc2a562c89fd4706a6c1b93923686e7a42 Mon Sep 17 00:00:00 2001 From: Florian Deljarry Date: Tue, 12 Jun 2018 11:11:00 -0400 Subject: [PATCH 6/7] Adding reading method Add: - Reading null variables and instances - Using step interpreter to interpretation Signed-off-by: Florian Deljarry --- src/interpreter/interpreter.nit | 2 +- src/interpreter/naive_interpreter.nit | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/interpreter/interpreter.nit b/src/interpreter/interpreter.nit index 63e3ac3387..a000f9a187 100644 --- a/src/interpreter/interpreter.nit +++ b/src/interpreter/interpreter.nit @@ -15,5 +15,5 @@ # Interpretation of Nit programs module interpreter -import naive_interpreter +import step_interpreter import dynamic_loading_ffi diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index 799c413a0a..7cdceb480f 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -446,6 +446,14 @@ class NaiveInterpreter return f.map[v] end + # Retrieve the value of the variable in the current frame + fun read_null_variable(v: Variable):nullable Instance + do + var f = frames.first.as(InterpreterFrame) + if f.map.has_key(v) then return f.map[v] + return null + end + # Assign the value of the variable in the current frame fun write_variable(v: Variable, value: Instance) do @@ -453,6 +461,18 @@ class NaiveInterpreter f.map[v] = value end + # Retrieve the variable of the Instance in the current frame + fun read_instance(i: nullable Instance): nullable Variable + do + if i != null then + var f = frames.first.as(InterpreterFrame) + for key, value in f.map do + if value == i then return key + end + end + return null + end + # Store known methods, used to trace methods as they are reached var discover_call_trace: Set[MMethodDef] = new HashSet[MMethodDef] From 45b754c54bacfe610965bda46a13c7ec426e265c Mon Sep 17 00:00:00 2001 From: Florian Deljarry Date: Tue, 12 Jun 2018 11:36:01 -0400 Subject: [PATCH 7/7] Adding the breakpoint feature Adding the Possibility to add and remove breakpoint during the interpretationNew breakpoint future Signed-off-by: Florian Deljarry --- share/man/nit.md | 5 + src/interpreter/naive_interpreter.nit | 3 + src/interpreter/step_interpreter.nit | 126 +++++++++++++++++- tests/sav/error_class_glob.res | 26 ++-- .../nitce/fixme/base_gen_reassign_alt4.res | 2 +- .../nitce/fixme/base_gen_reassign_alt5.res | 2 +- .../nitce/fixme/base_gen_reassign_alt6.res | 2 +- tests/sav/nituml_args3.res | 2 +- tests/sav/nituml_args4.res | 2 +- 9 files changed, 150 insertions(+), 20 deletions(-) diff --git a/share/man/nit.md b/share/man/nit.md index 7d30a09f0f..d210fcf540 100644 --- a/share/man/nit.md +++ b/share/man/nit.md @@ -86,6 +86,11 @@ Each time a method is invoked for the first time, its information is printed on This option helps the user to have a simplified but humanly readable overview of the behavior of a particular program execution. +### `--break` +Start the program to indicate the breakpoints for the interpretation. + +Print the menu to add or remove some breakpoint + ## DEBUGGER OPTIONS ### `-d` diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index 7cdceb480f..90bfb3cea7 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -27,11 +27,14 @@ private import frontend::explain_assert_api redef class ToolContext # --discover-call-trace var opt_discover_call_trace = new OptionBool("Trace calls of the first invocation of methods", "--discover-call-trace") + # --stop-at + var opt_stop = new OptionBool("Start the program to indicate the breakpoints for the interpretation","--break") redef init do super self.option_context.add_option(self.opt_discover_call_trace) + self.option_context.add_option(self.opt_stop) end end diff --git a/src/interpreter/step_interpreter.nit b/src/interpreter/step_interpreter.nit index 544db1ffb8..ae38930995 100644 --- a/src/interpreter/step_interpreter.nit +++ b/src/interpreter/step_interpreter.nit @@ -36,8 +36,20 @@ redef class NaiveInterpreter # This flag is used to launch setp by step interpreter var debug_flag = false + # The breakpoint tool + private var breakpoint : Breakpoints + + # The user entry is use for the step by step execution private var user_entry = "" + init do + super + breakpoint = new Breakpoints(self.modelbuilder) + if modelbuilder.toolcontext.opt_stop.value then + breakpoint.define_breakpoints + end + end + # Print the commands to execute step-by-step execution fun print_instruction_debug do print "────────────────────────────────────────────────────────────────────" @@ -85,6 +97,10 @@ redef class NaiveInterpreter # Main function of the step-by-step execution this method is called after each instruction fun step_execution(recv : nullable Instance) do + if frame isa InterpreterFrame and breakpoint.is_breakpoint(frame.current_node.location) then + self.deep_old_frame = frames.length + self.debug_flag = true + end if self.debug_flag then init_debug_mode if recv != null then @@ -102,6 +118,9 @@ redef class NaiveInterpreter self.object_inspector.print_pin_list_value self.user_entry = stdin.read_line self.step_execution(recv) + else if user_entry == "break" then + self.user_entry = "" + self.breakpoint.define_breakpoints else if user_entry == "continue" then self.user_entry = "" self.debug_flag = false @@ -111,6 +130,8 @@ redef class NaiveInterpreter end end + # Step into method + # He execute the step-by-step execution in the method fun step_into do print "{self.get_color_line}" deep_old_frame = frames.length @@ -118,6 +139,8 @@ redef class NaiveInterpreter old_line_number = frame.current_node.location.line_start end + # Step over method + # He keep the step-by-step execution in the method fun step_over do # Check if the new instruction is in the same method or the new instruction is in the appellant method # Check the line to execute all instruction line @@ -126,7 +149,7 @@ redef class NaiveInterpreter end end - redef fun expr(n: AExpr): nullable Instance + redef fun expr(n) do var i = super if i != null then step_execution(i) @@ -142,6 +165,105 @@ redef class NaiveInterpreter super end end + +class Breakpoints + + # The map representing the breakpoints with the links of the source file and array of lines + private var breakpoints_list = new ArrayMap[SourceFile,Array[Int]] + + # The modelbuilder is stored to check the module + var modelbuilder: ModelBuilder + + redef fun to_s do + var return_list = "" + for file, lines in breakpoints_list do + return_list += "File : {file.filename} lines : {lines} \n" + end + return return_list + end + + # Is there location is a breakpoint? + fun is_breakpoint(location : Location): Bool do + if breakpoints_list.has_key(location.file) then + return breakpoints_list[location.file].has(location.line_start) + end + return false + end + + # Method to interact with the breakpoints list + fun define_breakpoints do + print "────────────────────────────────────────────────────────────────────" + print "Breakpoints list" + print "{self.to_s}" + print "For add enter" + " 'break [file name] [line number,...]'".yellow + " for remove " + "'clear [file name] [line number,...]'".yellow + print "To leave the breakpoint mode enter " + "leave".yellow + print "────────────────────────────────────────────────────────────────────" + var user_entry = stdin.read_line.split(" ") + if user_entry.length%3 == 0 then + for x in [0 .. user_entry.length[.step(3) do + var action = user_entry[x] + var file = check_file(user_entry[x+1]) + var lines = check_line(user_entry[x+2]) + if file != null then + if action == "break" then + add_breakpoints(file,lines) + else if action == "clear" then + remove_breakpoint(file,lines) + else + print "Command unknown" + end + end + end + else + print "Error on the number of parameters" + end + end + + # Check in the list of modules the source file exists with the name of the parameter. + # If it exists, return this. + fun check_file(name: String) : nullable SourceFile do + for mmodule in modelbuilder.identified_modules do + if mmodule.location.file.filename.search(name) != null then return mmodule.location.file + end + print "File not found" + return null + end + + # Check the user input line. + fun check_line(string_line: String) : Array[Int] do + var lines = string_line.split(",") + var return_array = new Array[Int] + for line in lines do + if line.is_int then + return_array.add(line.to_i) + end + end + return return_array + end + + # Method to add an breakpoint + # Take a source file and an lines array representing the breakpoints + fun add_breakpoints(file : SourceFile,lines : Array[Int])do + if not lines.is_empty then + if breakpoints_list.has_key(file) then + breakpoints_list[file].add_all(lines) + else + breakpoints_list[file] = lines + end + end + end + + # Method to remove an breakpoint + # Take a source file and an lines array representing the breakpoints + fun remove_breakpoint(file : SourceFile,lines : Array[Int])do + if not lines.is_empty then + for line in lines do + breakpoints_list[file].remove_all(line) + end + end + end +end + # Represents the inspected object with the relationship between the instance and the name of the object (if it exists) class ObjectInspected # The instance of the inspected object. @@ -313,7 +435,7 @@ class ObjectInspector end redef class AMethPropdef - redef fun intern_call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance + redef fun intern_call(v,mpropdef,args) do var pname = mpropdef.mproperty.name if pname == "inspect_o" then diff --git a/tests/sav/error_class_glob.res b/tests/sav/error_class_glob.res index 46e2b1aed4..504e245e89 100644 --- a/tests/sav/error_class_glob.res +++ b/tests/sav/error_class_glob.res @@ -1,13 +1,13 @@ -../lib/core/kernel.nit:32,1--225,3: Error: `kernel$Object` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:227,1--300,3: Error: `kernel$Sys` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:313,1--371,3: Error: `kernel$Comparable` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:373,1--410,3: Error: `kernel$Discrete` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:412,1--429,3: Error: `kernel$Cloneable` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:431,1--486,3: Error: `kernel$Numeric` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:492,1--515,3: Error: `kernel$Bool` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:517,1--599,3: Error: `kernel$Float` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:601,1--700,3: Error: `kernel$Byte` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:702,1--883,3: Error: `kernel$Int` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:885,1--1064,3: Error: `kernel$Char` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:1066,1--1083,3: Error: `kernel$Pointer` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? -../lib/core/kernel.nit:1085,1--1094,3: Error: `kernel$Task` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:32,1--230,3: Error: `kernel$Object` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:232,1--305,3: Error: `kernel$Sys` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:318,1--376,3: Error: `kernel$Comparable` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:378,1--415,3: Error: `kernel$Discrete` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:417,1--434,3: Error: `kernel$Cloneable` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:436,1--491,3: Error: `kernel$Numeric` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:497,1--520,3: Error: `kernel$Bool` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:522,1--604,3: Error: `kernel$Float` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:606,1--705,3: Error: `kernel$Byte` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:707,1--888,3: Error: `kernel$Int` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:890,1--1069,3: Error: `kernel$Char` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:1071,1--1088,3: Error: `kernel$Pointer` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? +../lib/core/kernel.nit:1090,1--1099,3: Error: `kernel$Task` does not specialize `module_0$Object`. Possible duplication of the root class `Object`? diff --git a/tests/sav/nitce/fixme/base_gen_reassign_alt4.res b/tests/sav/nitce/fixme/base_gen_reassign_alt4.res index 5bdd4bf614..e131b2ec7a 100644 --- a/tests/sav/nitce/fixme/base_gen_reassign_alt4.res +++ b/tests/sav/nitce/fixme/base_gen_reassign_alt4.res @@ -1,4 +1,4 @@ -Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723) +Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728) 11 21 31 diff --git a/tests/sav/nitce/fixme/base_gen_reassign_alt5.res b/tests/sav/nitce/fixme/base_gen_reassign_alt5.res index 5bdd4bf614..e131b2ec7a 100644 --- a/tests/sav/nitce/fixme/base_gen_reassign_alt5.res +++ b/tests/sav/nitce/fixme/base_gen_reassign_alt5.res @@ -1,4 +1,4 @@ -Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723) +Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728) 11 21 31 diff --git a/tests/sav/nitce/fixme/base_gen_reassign_alt6.res b/tests/sav/nitce/fixme/base_gen_reassign_alt6.res index 5bdd4bf614..e131b2ec7a 100644 --- a/tests/sav/nitce/fixme/base_gen_reassign_alt6.res +++ b/tests/sav/nitce/fixme/base_gen_reassign_alt6.res @@ -1,4 +1,4 @@ -Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:723) +Runtime error: Cast failed. Expected `OTHER`, got `Float` (../lib/core/kernel.nit:728) 11 21 31 diff --git a/tests/sav/nituml_args3.res b/tests/sav/nituml_args3.res index a5a027f67e..fe264cef63 100644 --- a/tests/sav/nituml_args3.res +++ b/tests/sav/nituml_args3.res @@ -12,7 +12,7 @@ digraph G { fontsize = 8 ] Object [ - label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l+ init()\l}" + label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ inspect_o()\l+ sys(): Sys\l+ init()\l}" ] Sys [ diff --git a/tests/sav/nituml_args4.res b/tests/sav/nituml_args4.res index f03123ae1a..3223febd04 100644 --- a/tests/sav/nituml_args4.res +++ b/tests/sav/nituml_args4.res @@ -12,7 +12,7 @@ digraph G { fontsize = 8 ] Object [ - label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l+ init()\l}" + label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ inspect_o()\l+ sys(): Sys\l+ init()\l}" ] Sys [