CrossLanguageStepOverHandler, CrossLanguageStepIntoHandler, ASTNodeBreakpointMapper, BreakpointSyncOrchestrator — 26/26 tests pass. Integration step 1932: Go+TypeScript poly-API round-trip verified. Metrics: 7 whetstone calls, 5587 tokens. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
117 lines
4.0 KiB
C++
117 lines
4.0 KiB
C++
// Step 1928: CrossLanguageStepOverHandler
|
|
//
|
|
// t1: isAtBoundary delegates to frame.isBoundary
|
|
// t2: stepOver at non-boundary returns crossed=false, no router change
|
|
// t3: stepOver at boundary returns crossed=true, sets router to frame language
|
|
// t4: stepOver records previousLanguage correctly
|
|
// t5: successive step-overs across multiple boundary frames
|
|
|
|
#include "CrossLanguageStepOverHandler.h"
|
|
#include "PolyglotStackTraceDecoder.h"
|
|
#include "DebugAdapterRouter.h"
|
|
#include <iostream>
|
|
|
|
namespace ws = whetstone;
|
|
static int p=0,f=0;
|
|
#define T(n) { std::cout<<" "<<#n<<"... "; }
|
|
#define P() { std::cout<<"PASS\n"; ++p; }
|
|
#define F(m) { std::cout<<"FAIL: "<<m<<"\n"; ++f; }
|
|
#define C(c,m) if(!(c)){F(m);return;}
|
|
|
|
static ws::DebugAdapterRouter makeRouter() {
|
|
ws::DebugAdapterRouter r;
|
|
r.registerAdapter("Python", {"stackTrace","continue","stepIn","next"});
|
|
r.registerAdapter("Rust", {"stackTrace","continue","next"});
|
|
r.setActiveLanguage("Python");
|
|
return r;
|
|
}
|
|
|
|
static std::vector<ws::StackFrame> makeStack() {
|
|
ws::PolyglotStackTraceDecoder dec;
|
|
return dec.decode({
|
|
{1,"run", "main.py", 10},
|
|
{2,"generate", "gen.py", 20}, // boundary (next is Rust)
|
|
{3,"sort_array","sort.rs", 5}, // boundary (prev is Python)
|
|
{4,"partition", "sort.rs", 15},
|
|
});
|
|
}
|
|
|
|
void t1(){
|
|
T(isAtBoundary_delegates_to_frame);
|
|
ws::CrossLanguageStepOverHandler h;
|
|
auto frames = makeStack();
|
|
C(!h.isAtBoundary(frames[0]), "frame0 not boundary");
|
|
C( h.isAtBoundary(frames[1]), "frame1 boundary");
|
|
C( h.isAtBoundary(frames[2]), "frame2 boundary");
|
|
C(!h.isAtBoundary(frames[3]), "frame3 not boundary");
|
|
P();
|
|
}
|
|
|
|
void t2(){
|
|
T(stepOver_non_boundary_returns_not_crossed);
|
|
ws::CrossLanguageStepOverHandler h;
|
|
auto router = makeRouter();
|
|
auto frames = makeStack();
|
|
auto r = h.stepOver(frames[0], router);
|
|
C(!r.crossed, "not crossed");
|
|
C(r.previousLanguage.empty(), "no previous");
|
|
C(r.newLanguage.empty(), "no new");
|
|
C(router.getActiveLanguage() == "Python", "router unchanged");
|
|
P();
|
|
}
|
|
|
|
void t3(){
|
|
T(stepOver_boundary_sets_router_to_frame_language);
|
|
ws::CrossLanguageStepOverHandler h;
|
|
auto router = makeRouter();
|
|
auto frames = makeStack();
|
|
// frame[1] is Python boundary — step-over stays in Python (caller side)
|
|
auto r = h.stepOver(frames[1], router);
|
|
C( r.crossed, "crossed");
|
|
C( r.newLanguage == "Python", "stays in Python");
|
|
C( router.getActiveLanguage() == "Python", "router set to Python");
|
|
P();
|
|
}
|
|
|
|
void t4(){
|
|
T(stepOver_records_previousLanguage);
|
|
ws::CrossLanguageStepOverHandler h;
|
|
auto router = makeRouter();
|
|
router.setActiveLanguage("Rust");
|
|
auto frames = makeStack();
|
|
// frame[2] is Rust, boundary — step-over sets router to Rust
|
|
auto r = h.stepOver(frames[2], router);
|
|
C(r.crossed, "crossed");
|
|
C(r.previousLanguage == "Rust","previous was Rust");
|
|
C(r.newLanguage == "Rust", "new is Rust (frame language)");
|
|
P();
|
|
}
|
|
|
|
void t5(){
|
|
T(successive_stepOvers);
|
|
ws::CrossLanguageStepOverHandler h;
|
|
ws::PolyglotStackTraceDecoder dec;
|
|
auto frames = dec.decode({
|
|
{1,"a","a.py",1},{2,"b","b.rs",1},{3,"c","c.go",1}
|
|
});
|
|
auto router = makeRouter();
|
|
router.registerAdapter("Go", {"continue"});
|
|
router.setActiveLanguage("Python");
|
|
// All three frames are boundaries
|
|
for (auto& fr : frames) C(h.isAtBoundary(fr), fr.name + " is boundary");
|
|
// Step-over frame[0] (Python): stays Python
|
|
auto r0 = h.stepOver(frames[0], router);
|
|
C(r0.newLanguage == "Python", "step-over0 stays Python");
|
|
// Step-over frame[1] (Rust): router goes to Rust
|
|
auto r1 = h.stepOver(frames[1], router);
|
|
C(r1.newLanguage == "Rust", "step-over1 to Rust");
|
|
P();
|
|
}
|
|
|
|
int main(){
|
|
std::cout << "Step 1928: CrossLanguageStepOverHandler\n";
|
|
t1(); t2(); t3(); t4(); t5();
|
|
std::cout << "\n" << p << "/" << (p+f) << " passed\n";
|
|
return f > 0 ? 1 : 0;
|
|
}
|