Skip to content

Commit

Permalink
Fix crash when func has no block (#774)
Browse files Browse the repository at this point in the history
  • Loading branch information
TwitchBronBron committed Feb 21, 2023
1 parent 8d3d74e commit 4b22eb6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
13 changes: 7 additions & 6 deletions src/parser/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -887,12 +887,13 @@ export class Parser {

this._references.functionExpressions.push(func);

//make sure to restore the currentFunctionExpression even if the body block fails to parse
try {
//support ending the function with `end sub` OR `end function`
func.body = this.block();
func.body.symbolTable = new SymbolTable(`Block: Function '${name?.text ?? ''}'`, () => func.getSymbolTable());
} finally { }
//support ending the function with `end sub` OR `end function`
func.body = this.block();
//if the parser was unable to produce a block, make an empty one so the AST makes some sense...
if (!func.body) {
func.body = new Block([], util.createRangeFromPositions(func.range.start, func.range.start));
}
func.body.symbolTable = new SymbolTable(`Block: Function '${name?.text ?? ''}'`, () => func.getSymbolTable());

if (!func.body) {
this.diagnostics.push({
Expand Down
12 changes: 11 additions & 1 deletion src/parser/tests/statement/Function.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import { expect } from '../../../chai-config.spec';

import { Parser } from '../../Parser';
import { Lexer } from '../../../lexer/Lexer';
import { TokenKind } from '../../../lexer/TokenKind';
import { EOF, identifier, token } from '../Parser.spec';
import { isFunctionStatement } from '../../../astUtils/reflection';
import type { FunctionStatement } from '../../Statement';

describe('parser', () => {

describe('function declarations', () => {
it('still provides a body when end keyword is mangled/missing', () => {
const parser = Parser.parse(`
sub test()
end su
`);
const func = parser.ast.findChild<FunctionStatement>(isFunctionStatement);
expect(func.func.body).to.exist;
});

it('recovers when using `end sub` instead of `end function`', () => {
const { tokens } = Lexer.scan(`
function Main()
Expand Down

0 comments on commit 4b22eb6

Please sign in to comment.