Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent errors when using enums in a file that's not included in any scopes #995

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ export class Program {
/**
* Get the first found scope for a file.
*/
public getFirstScopeForFile(file: XmlFile | BrsFile): Scope {
public getFirstScopeForFile(file: XmlFile | BrsFile): Scope | undefined {
for (let key in this.scopes) {
let scope = this.scopes[key];

Expand Down
2 changes: 1 addition & 1 deletion src/Scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,7 @@ export class Scope {
}
}

interface NamespaceContainer {
export interface NamespaceContainer {
file: BscFile;
fullName: string;
nameRange: Range;
Expand Down
9 changes: 5 additions & 4 deletions src/bscPlugin/CallExpressionInfo.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { Expression } from '../parser/AstNode';
import type { CallExpression, CallfuncExpression, NewExpression } from '../parser/Expression';
import type { ClassStatement, NamespaceStatement } from '../parser/Statement';
import type { ClassStatement } from '../parser/Statement';
import { isCallExpression, isCallfuncExpression, isVariableExpression, isDottedGetExpression, isClassStatement, isNewExpression } from '../astUtils/reflection';
import type { BrsFile } from '../files/BrsFile';
import type { Position } from 'vscode-languageserver-protocol';
import { util } from '../util';
import { ParseMode } from '../parser/Parser';
import type { NamespaceContainer } from '../Scope';


export enum CallExpressionType {
Expand All @@ -29,7 +30,7 @@ export class CallExpressionInfo {

file: BrsFile;
myClass: ClassStatement;
namespace: NamespaceStatement;
namespace?: NamespaceContainer;
dotPart: string;
name: string;
isCallingMethodOnMyClass: boolean;
Expand Down Expand Up @@ -80,7 +81,7 @@ export class CallExpressionInfo {
let parts = util.getAllDottedGetParts(callExpression.callee);
parts.splice(parts?.length - 1, 1);
this.dotPart = parts.map(x => x.text).join('.');
this.namespace = this.getNamespace(this.dotPart, this.file);
this.namespace = this.getNamespace();
}
}

Expand Down Expand Up @@ -142,7 +143,7 @@ export class CallExpressionInfo {

}

private getNamespace(dotPart: string, file: BrsFile): any {
private getNamespace(): NamespaceContainer {
let scope = this.file.program.getFirstScopeForFile(this.file);
return scope.namespaceLookup.get(this.dotPart);
}
Expand Down
17 changes: 16 additions & 1 deletion src/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import * as fsExtra from 'fs-extra';
import { Program } from '../../Program';
import { standardizePath as s } from '../../util';
import { tempDir, rootDir } from '../../testHelpers.spec';
import { Logger, LogLevel } from '../../Logger';
import PluginInterface from '../../PluginInterface';
const sinon = createSandbox();

describe('BrsFile', () => {
Expand All @@ -11,8 +13,13 @@ describe('BrsFile', () => {

beforeEach(() => {
fsExtra.emptyDirSync(tempDir);
program = new Program({ rootDir: rootDir, sourceMap: true });
const logger = new Logger(LogLevel.warn);
program = new Program({ rootDir: rootDir, sourceMap: true }, logger, new PluginInterface([], {
logger: logger,
suppressErrors: false
}));
});

afterEach(() => {
sinon.restore();
program.dispose();
Expand All @@ -21,11 +28,19 @@ describe('BrsFile', () => {
describe('BrsFilePreTranspileProcessor', () => {
it('does not crash when operating on a file not included by any scope', async () => {
program.setFile('components/lib.brs', `
enum Direction
up
down
left
right
end enum
sub doSomething()
a = { b: "c"}
print a.b
print Direction.up
end sub
`);

await program.transpile([], s`${tempDir}/out`);
});
});
Expand Down
6 changes: 3 additions & 3 deletions src/bscPlugin/transpile/BrsFilePreTranspileProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ export class BrsFilePreTranspileProcessor {
* Given a string optionally separated by dots, find an enum related to it.
* For example, all of these would return the enum: `SomeNamespace.SomeEnum.SomeMember`, SomeEnum.SomeMember, `SomeEnum`
*/
private getEnumInfo(name: string, containingNamespace: string, scope: Scope) {
private getEnumInfo(name: string, containingNamespace: string, scope: Scope | undefined) {

//do we have an enum MEMBER reference? (i.e. SomeEnum.someMember or SomeNamespace.SomeEnum.SomeMember)
let memberLink = scope.getEnumMemberFileLink(name, containingNamespace);
let memberLink = scope?.getEnumMemberFileLink(name, containingNamespace);
if (memberLink) {
const value = memberLink.item.getValue();
return {
Expand All @@ -65,7 +65,7 @@ export class BrsFilePreTranspileProcessor {

}

private processExpression(expression: Expression, scope: Scope) {
private processExpression(expression: Expression, scope: Scope | undefined) {
let containingNamespace = this.event.file.getNamespaceStatementForPosition(expression.range.start)?.getName(ParseMode.BrighterScript);

const parts = util.splitExpression(expression);
Expand Down