From b5701dae7d198d3b5435f89f5768499aa260da42 Mon Sep 17 00:00:00 2001 From: Dave Holoway Date: Sun, 30 May 2021 19:31:33 +0100 Subject: [PATCH] identify breakpoint source locations by package and filename instead of type name --- src/debugger-types.js | 6 +++++- src/debugger.js | 7 +++++-- src/utils/source-file.js | 6 +++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/debugger-types.js b/src/debugger-types.js index a4b8e21..49ae03b 100644 --- a/src/debugger-types.js +++ b/src/debugger-types.js @@ -610,12 +610,16 @@ class DebuggerBreakpoint { const cls = splitSourcePath(srcfpn); this.id = DebuggerBreakpoint.makeBreakpointID(srcfpn, linenum); this.srcfpn = srcfpn; + this.file = cls.file; this.qtype = cls.qtype; this.pkg = cls.pkg; this.type = cls.type; this.linenum = linenum; this.options = options; - this.sigpattern = new RegExp(`^L${cls.qtype}([$][$a-zA-Z0-9_]+)?;$`), + // sigpattern is used to match up source files with class signatures but because + // kotlin allows filenames that differ from class names, we now only match up to + // the package level and use the source name retuned by JDWP to narrow it down futher. + this.sigpattern = new RegExp(`^L${cls.pkg.replace(/[.]/g, '/')}/[^/]+;$`) this.state = initialState; // set,notloaded,enabled,removed this.hitcount = 0; // number of times this bp was hit during execution this.stopcount = 0; // number of times this bp caused a break into the debugger diff --git a/src/debugger.js b/src/debugger.js index 54651bd..83b0bf7 100644 --- a/src/debugger.js +++ b/src/debugger.js @@ -567,13 +567,15 @@ class Debugger extends EventEmitter { * @param {DebuggerBreakpoint} bp */ async initialiseBreakpoint(bp) { - // try and load the class - if the runtime hasn't loaded it yet, this will just return a TypeNotAvailable instance + // try and load the classes in the package - if the runtime hasn't loaded it yet, this will just return a TypeNotAvailable instance let classes = await Promise.all( [...this.session.loadedClasses] .filter(signature => bp.sigpattern.test(signature)) .map(signature => this.loadClassInfo(signature)) ); - let bploc = Debugger.findBreakpointLocation(classes, bp); + // find classes with a matching sourcefile name + classes = classes.filter(c => c.src.sourcefile === bp.file); + const bploc = Debugger.findBreakpointLocation(classes, bp); if (!bploc) { // we couldn't identify a matching location - either the class is not yet loaded or the // location doesn't correspond to any code. In case it's the former, make sure we are notified @@ -1661,6 +1663,7 @@ class Debugger extends EventEmitter { let bploc = null; classes.find(c => bp.sigpattern.test(c.type.signature) + && bp.file === c.src.sourcefile && c.methods.find(m => { const line = m.linetable.lines.find(line => line.linenum === bp.linenum); if (line) { diff --git a/src/utils/source-file.js b/src/utils/source-file.js index 8b5103e..2617164 100644 --- a/src/utils/source-file.js +++ b/src/utils/source-file.js @@ -6,12 +6,16 @@ function hasValidSourceFileExtension(s) { return /\.(java|kt)$/i.test(s); } +/** + * @param {string} filepath + */ function splitSourcePath(filepath) { - const m = filepath.match(/^\/([^/]+(?:\/[^/]+)*)?\/([^./]+)\.(java|kt)$/); + const m = filepath.match(/^\/([^/]+(?:\/[^/]+)*)?\/([^./]+)\.(java|kt)$/i); return { pkg: m[1].replace(/\/+/g, '.'), type: m[2], qtype: `${m[1]}/${m[2]}`, + file: `${m[2]}.${m[3]}`, } }