1+ #!/usr/bin/env node
2+
3+ /**
4+ * Test to verify that interface static method calls are parsed correctly.
5+ * This addresses the bug where jvm_parser fails with TypeError when parsing
6+ * class files containing calls to interface static methods.
7+ */
8+
9+ const fs = require ( 'fs' ) ;
10+ const { getAST, getDisassembled } = require ( './lib' ) ;
11+
12+ function test_interface_static_methods ( ) {
13+ console . log ( 'Testing interface static method parsing...\n' ) ;
14+
15+ try {
16+ // Test with MinimalBug.class (contains interface static method call)
17+ console . log ( '✓ Testing MinimalBug.class (interface static method call)...' ) ;
18+ const minimalBugBytes = fs . readFileSync ( 'MinimalBug.class' ) ;
19+ const minimalBugAST = getAST ( minimalBugBytes ) ;
20+
21+ if ( ! minimalBugAST . ast ) {
22+ throw new Error ( 'AST is missing' ) ;
23+ }
24+
25+ if ( ! minimalBugAST . ast . methods || minimalBugAST . ast . methods . length === 0 ) {
26+ throw new Error ( 'Methods are missing from MinimalBug AST' ) ;
27+ }
28+
29+ console . log ( ` - Found ${ minimalBugAST . ast . methods . length } method(s)` ) ;
30+
31+ // Find the main method and check that it has bytecode
32+ const mainMethod = minimalBugAST . ast . methods . find ( m => m . name === 'main' ) ;
33+ if ( ! mainMethod ) {
34+ throw new Error ( 'main method not found' ) ;
35+ }
36+
37+ console . log ( ' - Found main method' ) ;
38+
39+ // Check that main method has code with instructions
40+ if ( ! mainMethod . code || ! mainMethod . code . instructions ) {
41+ throw new Error ( 'main method missing code or instructions' ) ;
42+ }
43+
44+ console . log ( ` - main method has ${ mainMethod . code . instructions . length } instruction(s)` ) ;
45+
46+ // Look for the invokestatic instruction that calls the interface method
47+ const invokeStaticInstr = mainMethod . code . instructions . find ( instr =>
48+ instr . opcode === 184 && instr . comment && instr . comment . includes ( 'doSomething' )
49+ ) ;
50+
51+ if ( ! invokeStaticInstr ) {
52+ throw new Error ( 'Expected invokestatic instruction calling doSomething not found' ) ;
53+ }
54+
55+ console . log ( ' - Found invokestatic instruction with interface method call' ) ;
56+ console . log ( ` - Instruction comment: ${ invokeStaticInstr . comment } ` ) ;
57+
58+ // Test that we can also generate disassembled output
59+ console . log ( '✓ Testing disassembly of interface static method call...' ) ;
60+ const disassembled = getDisassembled ( minimalBugBytes ) ;
61+
62+ if ( ! disassembled . includes ( 'doSomething' ) ) {
63+ throw new Error ( 'Disassembled output does not contain interface method name' ) ;
64+ }
65+
66+ console . log ( ' - Disassembly successful' ) ;
67+
68+ console . log ( '\n🎉 Interface static method parsing test passed!' ) ;
69+ return true ;
70+
71+ } catch ( error ) {
72+ console . error ( '\n❌ Interface static method parsing test failed:' , error . message ) ;
73+ throw error ;
74+ }
75+ }
76+
77+ // Run the test
78+ try {
79+ test_interface_static_methods ( ) ;
80+ process . exit ( 0 ) ;
81+ } catch ( error ) {
82+ process . exit ( 1 ) ;
83+ }
0 commit comments