Skip to content

Commit

Permalink
Fix transpile for namespaced class constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
TwitchBronBron committed Oct 12, 2020
1 parent a9f10f2 commit f075612
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
38 changes: 38 additions & 0 deletions src/files/BrsFile.Class.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,44 @@ describe('BrsFile BrighterScript classes', () => {
`, undefined, 'source/main.bs');
});

it('properly transpiles classes from outside current namespace', async () => {
await addFile('source/Animals.bs', `
namespace Animals
class Duck
end class
end namespace
class Bird
end class
`);
await testTranspile(`
namespace Animals
sub init()
donaldDuck = new Duck()
daffyDuck = new Animals.Duck()
bigBird = new Bird()
end sub
end namespace
`, `
sub Animals_init()
donaldDuck = Animals_Duck()
daffyDuck = Animals_Duck()
bigBird = Bird()
end sub
`, undefined, 'source/main.bs');
});

it('properly transpiles new statement for missing class ', async () => {
await testTranspile(`
sub main()
bob = new Human()
end sub
`, `
sub main()
bob = Human()
end sub
`, undefined, 'source/main.bs');
});

it('new keyword transpiles correctly', async () => {
await addFile('source/Animal.bs', `
class Animal
Expand Down
19 changes: 16 additions & 3 deletions src/parser/Expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ export class CallExpression extends Expression {
readonly openingParen: Token,
readonly closingParen: Token,
readonly args: Expression[],
/**
* The namespace that currently wraps this call expression. This is NOT the namespace of the callee...that will be represented in the callee expression itself.
*/
readonly namespaceName: NamespacedVariableNameExpression
) {
super();
Expand All @@ -75,11 +78,15 @@ export class CallExpression extends Expression {

public readonly range: Range;

transpile(state: TranspileState) {
transpile(state: TranspileState, nameOverride?: string) {
let result = [];

//transpile the name
result.push(...this.callee.transpile(state));
if (nameOverride) {
result.push(state.sourceNode(this.callee, nameOverride));
} else {
result.push(...this.callee.transpile(state));
}

result.push(
new SourceNode(this.openingParen.range.start.line + 1, this.openingParen.range.start.character, state.pathAbsolute, '(')
Expand Down Expand Up @@ -845,7 +852,13 @@ export class NewExpression extends Expression {
public readonly range: Range;

public transpile(state: TranspileState) {
return this.call.transpile(state);
const cls = state.file.getClassByName(
this.className.getName(ParseMode.BrighterScript),
this.namespaceName?.getName(ParseMode.BrighterScript)
);
//new statements within a namespace block can omit the leading namespace if the class resides in that same namespace.
//So we need to figure out if this is a namespace-omitted class, or if this class exists without a namespace.
return this.call.transpile(state, cls?.getName(ParseMode.BrightScript));
}

walk(visitor: WalkVisitor, options: WalkOptions) {
Expand Down
4 changes: 2 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -934,8 +934,8 @@ export class Util {
/**
* Given the class name text, return a namespace-prefixed name.
* If the name already has a period in it, or the namespaceName was not provided, return the class name as is.
* If the name does not have a period, and a namespaceName was provided, return the class name prepended
* by the namespace name
* If the name does not have a period, and a namespaceName was provided, return the class name prepended by the namespace name.
* If no namespace is provided, return the `className` unchanged.
*/
public getFulllyQualifiedClassName(className: string, namespaceName?: string) {
if (className.includes('.') === false && namespaceName) {
Expand Down

0 comments on commit f075612

Please sign in to comment.