Skip to content

Commit

Permalink
Transpile comments above annotations for common statement types.
Browse files Browse the repository at this point in the history
  • Loading branch information
TwitchBronBron committed Aug 13, 2024
1 parent d262997 commit 2a3dbae
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 8 deletions.
125 changes: 125 additions & 0 deletions src/files/BrsFile.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2509,6 +2509,131 @@ describe('BrsFile', () => {
`, 'trim', 'source/main.bs');
});

it('includes annotation comments for class', async () => {
await testTranspile(`
'comment1
@annotation
'comment2
@annotation()
'comment3
class Beta
end class
`, `
function __Beta_builder()
instance = {}
instance.new = sub()
end sub
return instance
end function
'comment1
'comment2
'comment3
function Beta()
instance = __Beta_builder()
instance.new()
return instance
end function
`, undefined, 'source/main.bs');
});

it('includes annotation comments for function', async () => {
await testTranspile(`
'comment1
@annotation
'comment2
@annotation()
'comment3
function alpha()
end function
`, `
'comment1
'comment2
'comment3
function alpha()
end function
`, undefined, 'source/main.bs');
});

it('includes annotation comments for enum', async () => {
await testTranspile(`
'comment1
@annotation
'comment2
@annotation()
'comment3
enum Direction
up = "up"
end enum
`, `
'comment1
'comment2
'comment3
`, undefined, 'source/main.bs');
});

it('includes annotation comments for const', async () => {
await testTranspile(`
'comment1
@annotation
'comment2
@annotation()
'comment3
const direction = "up"
`, `
'comment1
'comment2
'comment3
`, undefined, 'source/main.bs');
});

it('includes annotation comments for empty namespaces', async () => {
await testTranspile(`
'comment1
@annotation
'comment2
@annotation()
'comment3
namespace alpha
'comment4
@annotation
'comment5
@annotation()
'comment6
namespace beta
end namespace
end namespace
`, `
'comment1
'comment2
'comment3
'comment4
'comment5
'comment6
`, undefined, 'source/main.bs');
});

it('includes comments above namespaced method call', async () => {
await testTranspile(`
sub main()
'delay for a bit
utils.delay(sub()
end sub)
end sub
namespace utils
function delay(callback as function)
end function
end namespace
`, `
sub main()
'delay for a bit
utils_delay(sub()
end sub)
end sub
function utils_delay(callback as function)
end function
`, undefined, 'source/main.bs');
});

it('keeps end-of-line comments with their line', async () => {
await testTranspile(`
function DoSomething() 'comment 1
Expand Down
10 changes: 10 additions & 0 deletions src/parser/BrsTranspileState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Editor } from '../astUtils/Editor';
import type { BrsFile } from '../files/BrsFile';
import type { ClassStatement, ConditionalCompileStatement } from './Statement';
import { TranspileState } from './TranspileState';
import type { Statement } from './AstNode';

export class BrsTranspileState extends TranspileState {
public constructor(
Expand Down Expand Up @@ -45,4 +46,13 @@ export class BrsTranspileState extends TranspileState {
* Do not transpile leading comments
*/
public skipLeadingComments = false;

/**
* Transpile all leading trivia for a given statement, including comments mixed between annotations
*/
public transpileAnnotations(node: Statement) {
return (node?.annotations ?? []).map(x => {
return x.transpile(this);
});
}
}
4 changes: 3 additions & 1 deletion src/parser/Expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export class CallExpression extends Expression {

transpile(state: BrsTranspileState, nameOverride?: string) {
let result: TranspileResult = [];
throw new Error('crash');

//transpile the name
if (nameOverride) {
Expand Down Expand Up @@ -1828,7 +1829,8 @@ export class AnnotationExpression extends Expression {
}

transpile(state: BrsTranspileState) {
return [];
//transpile only our leading comments
return state.transpileComments(this.leadingTrivia);
}

walk(visitor: WalkVisitor, options: WalkOptions) {
Expand Down
23 changes: 16 additions & 7 deletions src/parser/Statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class Body extends Statement implements TypedefProvider {
}

transpile(state: BrsTranspileState) {
let result = [] as TranspileResult;
let result: TranspileResult = state.transpileAnnotations(this);
for (let i = 0; i < this.statements.length; i++) {
let statement = this.statements[i];
let previousStatement = this.statements[i - 1];
Expand Down Expand Up @@ -542,14 +542,17 @@ export class FunctionStatement extends Statement implements TypedefProvider {
return this.func.leadingTrivia;
}

transpile(state: BrsTranspileState) {
transpile(state: BrsTranspileState): TranspileResult {
//create a fake token using the full transpiled name
let nameToken = {
...this.tokens.name,
text: this.getName(ParseMode.BrightScript)
};

return this.func.transpile(state, nameToken);
return [
...state.transpileAnnotations(this),
...this.func.transpile(state, nameToken)
];
}

getTypedef(state: BrsTranspileState) {
Expand Down Expand Up @@ -1686,6 +1689,7 @@ export class NamespaceStatement extends Statement implements TypedefProvider {
transpile(state: BrsTranspileState) {
//namespaces don't actually have any real content, so just transpile their bodies
return [
state.transpileAnnotations(this),
state.transpileLeadingComments(this.tokens.namespace),
this.body.transpile(state),
state.transpileLeadingComments(this.tokens.endNamespace)
Expand Down Expand Up @@ -2625,11 +2629,12 @@ export class ClassStatement extends Statement implements TypedefProvider {
* This invokes the builder, gets an instance of the class, then invokes the "new" function on that class.
*/
private getTranspiledClassFunction(state: BrsTranspileState) {
let result = [] as TranspileResult;
let result: TranspileResult = state.transpileAnnotations(this);
const constructorFunction = this.getConstructorFunction();
const constructorParams = constructorFunction ? constructorFunction.func.parameters : [];

result.push(
state.transpileLeadingComments(this.tokens.class),
state.sourceNode(this.tokens.class, 'function'),
state.sourceNode(this.tokens.class, ' '),
state.sourceNode(this.tokens.name, this.getName(ParseMode.BrightScript)),
Expand Down Expand Up @@ -3346,8 +3351,9 @@ export class EnumStatement extends Statement implements TypedefProvider {
}

transpile(state: BrsTranspileState) {
//enum declarations do not exist at runtime, so don't transpile anything...
//enum declarations don't exist at runtime, so just transpile comments and trivia
return [
state.transpileAnnotations(this),
state.transpileLeadingComments(this.tokens.enum)
];
}
Expand Down Expand Up @@ -3551,8 +3557,11 @@ export class ConstStatement extends Statement implements TypedefProvider {
}

public transpile(state: BrsTranspileState): TranspileResult {
//const declarations don't exist at runtime, so just transpile empty
return [state.transpileLeadingComments(this.tokens.const)];
//const declarations don't exist at runtime, so just transpile comments and trivia
return [
state.transpileAnnotations(this),
state.transpileLeadingComments(this.tokens.const)
];
}

getTypedef(state: BrsTranspileState): TranspileResult {
Expand Down

0 comments on commit 2a3dbae

Please sign in to comment.