Index: runtime/vm/debugger.cc |
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc |
index 5f14a55b5d82ae539b3440296112a5859ed59bce..fa29e7e5ed156f160c0ddd5a06627116f26365df 100644 |
--- a/runtime/vm/debugger.cc |
+++ b/runtime/vm/debugger.cc |
@@ -2649,37 +2649,46 @@ static void SelectBestFit(Function* best_fit, Function* func) { |
} |
+static bool IsTokenPosWithinFunction(const Function& func, TokenPosition pos) { |
+ return (func.token_pos() <= pos && pos <= func.end_token_pos()); |
+} |
+ |
+ |
RawFunction* Debugger::FindBestFit(const Script& script, |
TokenPosition token_pos) { |
Zone* zone = Thread::Current()->zone(); |
Class& cls = Class::Handle(zone); |
Array& functions = Array::Handle(zone); |
- GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
+ const GrowableObjectArray& closures = GrowableObjectArray::Handle( |
+ zone, isolate_->object_store()->closure_functions()); |
Function& function = Function::Handle(zone); |
Function& best_fit = Function::Handle(zone); |
Error& error = Error::Handle(zone); |
- closures = isolate_->object_store()->closure_functions(); |
const intptr_t num_closures = closures.Length(); |
for (intptr_t i = 0; i < num_closures; i++) { |
function ^= closures.At(i); |
- if (FunctionContains(function, script, token_pos)) { |
+ if (function.script() != script.raw()) { |
+ continue; |
+ } |
+ if (IsTokenPosWithinFunction(function, token_pos)) { |
+ // Select the inner most closure. |
SelectBestFit(&best_fit, &function); |
} |
} |
+ if (!best_fit.IsNull()) { |
+ // The inner most closure found will be the best fit. Going |
+ // over class functions below will not help in any further |
+ // narrowing. |
+ return best_fit.raw(); |
+ } |
const ClassTable& class_table = *isolate_->class_table(); |
const intptr_t num_classes = class_table.NumCids(); |
for (intptr_t i = 1; i < num_classes; i++) { |
if (class_table.HasValidClassAt(i)) { |
cls = class_table.At(i); |
- // Note: if this class has been parsed and finalized already, |
- // we need to check the functions of this class even if |
- // it is defined in a different 'script'. There could |
- // be mixin functions from the given script in this class. |
- // However, if this class is not parsed yet (not finalized), |
- // we can ignore it and avoid the side effect of parsing it. |
- if ((cls.script() != script.raw()) && !cls.is_finalized()) { |
+ if (cls.script() != script.raw()) { |
continue; |
} |
// Parse class definition if not done yet. |
@@ -2697,14 +2706,18 @@ RawFunction* Debugger::FindBestFit(const Script& script, |
for (intptr_t pos = 0; pos < num_functions; pos++) { |
function ^= functions.At(pos); |
ASSERT(!function.IsNull()); |
- if (FunctionContains(function, script, token_pos)) { |
- SelectBestFit(&best_fit, &function); |
+ if (IsTokenPosWithinFunction(function, token_pos)) { |
+ // Closures and inner functions within a class method are not |
+ // present in the functions of a class. Hence, we can return |
+ // right away as looking through other functions of a class |
+ // will not narrow down to any inner function/closure. |
+ return function.raw(); |
} |
} |
} |
} |
} |
- return best_fit.raw(); |
+ return Function::null(); |
} |