Skip to content

Commit

Permalink
Validate too deep nested files (#680)
Browse files Browse the repository at this point in the history
* Validate too deep nested files

* Reduce number of tests and fix lint errors

Co-authored-by: Bronley Plumb <bronley@gmail.com>
  • Loading branch information
iObject and TwitchBronBron committed Sep 1, 2022
1 parent e089eb7 commit f99e014
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/DiagnosticMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,11 @@ export let DiagnosticMessages = {
message: `Unexpected statement found outside of function body`,
code: 1133,
severity: DiagnosticSeverity.Error
}),
detectedTooDeepFileSource: (numberOfParentDirectories: number) => ({
message: `Expected directory depth no larger than 7, but found ${numberOfParentDirectories}.`,
code: 1134,
severity: DiagnosticSeverity.Error
})
};

Expand Down
20 changes: 20 additions & 0 deletions src/Scope.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,26 @@ describe('Scope', () => {
]);
});

it('Validates NOT too deep nested files', () => {
program.setFile('source/folder2/folder3/folder4/folder5/folder6/folder7/main.brs', ``);
program.setFile('source/folder2/folder3/folder4/folder5/folder6/folder7/main2.bs', ``);
program.setFile('components/folder2/folder3/folder4/folder5/folder6/folder7/ButtonSecondary.xml', `<component name="ButtonSecondary" extends="ButtonBase" />`);
program.validate();
expectZeroDiagnostics(program);
});

it('Validates too deep nested files', () => {
program.setFile('source/folder2/folder3/folder4/folder5/folder6/folder7/folder8/main.brs', ``);
program.setFile('source/folder2/folder3/folder4/folder5/folder6/folder7/folder8/main2.bs', ``);
program.setFile('components/folder2/folder3/folder4/folder5/folder6/folder7/folder8/ButtonSecondary.xml', `<component name="ButtonSecondary" extends="ButtonBase" />`);
program.validate();
expectDiagnostics(program, [
DiagnosticMessages.detectedTooDeepFileSource(8),
DiagnosticMessages.detectedTooDeepFileSource(8),
DiagnosticMessages.detectedTooDeepFileSource(8)
]);
});

it('detects unknown namespace sub-names', () => {
program.setFile('source/main.bs', `
sub main()
Expand Down
1 change: 1 addition & 0 deletions src/files/BrsFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ export class BrsFile {
}

public validate() {
util.validateTooDeepFile(this);
//only validate the file if it was actually parsed (skip files containing typedefs)
if (!this.hasTypedef) {
this.validateImportStatements();
Expand Down
1 change: 1 addition & 0 deletions src/files/XmlFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ export class XmlFile {


public validate() {
util.validateTooDeepFile(this);
if (this.parser.ast.root) {
this.validateComponent(this.parser.ast);
} else {
Expand Down
39 changes: 38 additions & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,32 @@ import type { DottedGetExpression, Expression, VariableExpression } from './pars
import { Logger, LogLevel } from './Logger';
import type { Identifier, Locatable, Token } from './lexer/Token';
import { TokenKind } from './lexer/TokenKind';
import { isCallExpression, isCallfuncExpression, isDottedGetExpression, isExpression, isIndexedGetExpression, isNamespacedVariableNameExpression, isVariableExpression, isXmlAttributeGetExpression } from './astUtils/reflection';
import { isBrsFile, isCallExpression, isCallfuncExpression, isDottedGetExpression, isExpression, isIndexedGetExpression, isNamespacedVariableNameExpression, isVariableExpression, isXmlAttributeGetExpression, isXmlFile } from './astUtils/reflection';
import { WalkMode } from './astUtils/visitors';
import { CustomType } from './types/CustomType';
import { SourceNode } from 'source-map';
import type { SGAttribute } from './parser/SGTypes';
import * as requireRelative from 'require-relative';
import type { BrsFile } from './files/BrsFile';
import type { XmlFile } from './files/XmlFile';

export class Util {
public clearConsole() {
// process.stdout.write('\x1Bc');
}

/**
* Returns the number of parent directories in the filPath
* @param filePath
*/
public getParentDirectoryCount(filePath: string | undefined) {
if (!filePath) {
return -1;
} else {
return filePath.replace(/^pkg:/, '').split(/[\\\/]/).length - 1;
}
}

/**
* Determine if the file exists
* @param filePath
Expand Down Expand Up @@ -1409,6 +1423,29 @@ export class Util {
public rangeToString(range: Range) {
return `${range?.start?.line}:${range?.start?.character}-${range?.end?.line}:${range?.end?.character}`;
}

public validateTooDeepFile(file: (BrsFile | XmlFile)) {
//find any files nested too deep
let pkgPath = file.pkgPath ?? file.pkgPath.toString();
let rootFolder = pkgPath.replace(/^pkg:/, '').split(/[\\\/]/)[0].toLowerCase();

if (isBrsFile(file) && rootFolder !== 'source') {
return;
}

if (isXmlFile(file) && rootFolder !== 'components') {
return;
}

let fileDepth = this.getParentDirectoryCount(pkgPath);
if (fileDepth >= 8) {
file.addDiagnostics([{
...DiagnosticMessages.detectedTooDeepFileSource(fileDepth),
file: file,
range: this.createRange(0, 0, 0, Number.MAX_VALUE)
}]);
}
}
}

/**
Expand Down

0 comments on commit f99e014

Please sign in to comment.