Skip to content

Commit 3002a20

Browse files
committed
feat(parser): add function boundary and parameter parsing
1 parent 04bfabd commit 3002a20

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

src/parsers/MapParser.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default class MapParser {
55
constructor(source) {
66
this.source = source;
77
this.lines = source.split('\n');
8+
this.functions = []; // Add this
89
}
910

1011
/**
@@ -69,4 +70,59 @@ export default class MapParser {
6970

7071
return assignments;
7172
}
73+
74+
/**
75+
* Parse function boundaries and parameters
76+
* @returns {Array<{name: string, startLine: number, endLine: number, parameters: string[]}>}
77+
*/
78+
parseFunctionBoundaries() {
79+
this.functions = [];
80+
const funcStartPattern = /^\s*Func\s+(\w+)\s*\((.*?)\)/i;
81+
const funcEndPattern = /^\s*EndFunc/i;
82+
83+
let currentFunc = null;
84+
85+
this.lines.forEach((line, index) => {
86+
const funcStart = line.match(funcStartPattern);
87+
if (funcStart) {
88+
// Parse parameters
89+
const paramsStr = funcStart[2].trim();
90+
const parameters = paramsStr
91+
? paramsStr.split(',').map(p => p.trim().split('=')[0].trim())
92+
: [];
93+
94+
currentFunc = {
95+
name: funcStart[1],
96+
startLine: index,
97+
endLine: -1,
98+
parameters
99+
};
100+
return;
101+
}
102+
103+
const funcEnd = line.match(funcEndPattern);
104+
if (funcEnd && currentFunc) {
105+
currentFunc.endLine = index;
106+
this.functions.push(currentFunc);
107+
currentFunc = null;
108+
}
109+
});
110+
111+
return this.functions;
112+
}
113+
114+
/**
115+
* Get the function containing a specific line
116+
* @param {number} line - Line number
117+
* @returns {object|null} Function object or null
118+
*/
119+
getFunctionAtLine(line) {
120+
if (this.functions.length === 0) {
121+
this.parseFunctionBoundaries();
122+
}
123+
124+
return this.functions.find(func =>
125+
line >= func.startLine && line <= func.endLine
126+
) || null;
127+
}
72128
}

test/parsers/MapParser.test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,71 @@ $mOther.key = "value"`;
106106
expect(assignments[0].key).toBe('name');
107107
});
108108
});
109+
110+
describe('parseFunctionBoundaries', () => {
111+
it('should detect function start and end', () => {
112+
const source = `Func MyFunction()
113+
Local $x = 1
114+
EndFunc`;
115+
const parser = new MapParser(source);
116+
const functions = parser.parseFunctionBoundaries();
117+
118+
expect(functions).toHaveLength(1);
119+
expect(functions[0]).toMatchObject({
120+
name: 'MyFunction',
121+
startLine: 0,
122+
endLine: 2,
123+
});
124+
});
125+
126+
it('should detect multiple functions', () => {
127+
const source = `Func First()
128+
EndFunc
129+
130+
Func Second()
131+
Local $x = 1
132+
EndFunc`;
133+
const parser = new MapParser(source);
134+
const functions = parser.parseFunctionBoundaries();
135+
136+
expect(functions).toHaveLength(2);
137+
expect(functions[0].name).toBe('First');
138+
expect(functions[1].name).toBe('Second');
139+
});
140+
141+
it('should detect function parameters', () => {
142+
const source = `Func ProcessUser($mUser, $name)
143+
EndFunc`;
144+
const parser = new MapParser(source);
145+
const functions = parser.parseFunctionBoundaries();
146+
147+
expect(functions).toHaveLength(1);
148+
expect(functions[0].parameters).toEqual(['$mUser', '$name']);
149+
});
150+
});
151+
152+
describe('getFunctionAtLine', () => {
153+
it('should return function containing the line', () => {
154+
const source = `Func MyFunction()
155+
Local $x = 1
156+
EndFunc`;
157+
const parser = new MapParser(source);
158+
parser.parseFunctionBoundaries();
159+
const func = parser.getFunctionAtLine(1);
160+
161+
expect(func).toBeDefined();
162+
expect(func.name).toBe('MyFunction');
163+
});
164+
165+
it('should return null for line outside functions', () => {
166+
const source = `Func MyFunction()
167+
EndFunc
168+
Local $x = 1`;
169+
const parser = new MapParser(source);
170+
parser.parseFunctionBoundaries();
171+
const func = parser.getFunctionAtLine(2);
172+
173+
expect(func).toBeNull();
174+
});
175+
});
109176
});

0 commit comments

Comments
 (0)