New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

brighterscript

Package Overview
Dependencies
Maintainers
1
Versions
300
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

brighterscript - npm Package Compare versions

Comparing version 0.35.0 to 0.36.0

14

CHANGELOG.md

@@ -9,2 +9,15 @@ # Changelog

## [0.36.0] - 2021-03-15
### Added
- class import code actions ([#365](https://github.com/rokucommunity/brighterscript/pull/365))
### Changed
- append stack trace to every language server error ([#354)](https://github.com/rokucommunity/brighterscript/pull/354))
### Fixed
- restrict function and class imports to .bs files only ([#365)](https://github.com/rokucommunity/brighterscript/pull/365))
- language server crashes due to unsafe property access in callfunc expressions ([#360)](https://github.com/rokucommunity/brighterscript/pull/360))
- crashes in signature help ([#358)](https://github.com/rokucommunity/brighterscript/pull/358))
- template string transpile bug when two expressions were next to each other ([#361)](https://github.com/rokucommunity/brighterscript/pull/361))
## [0.35.0] - 2021-03-09

@@ -1044,1 +1057,2 @@ ### Added

[0.35.0]: https://github.com/rokucommunity/brighterscript/compare/v0.34.3...v0.35.0
[0.36.0]: https://github.com/rokucommunity/brighterscript/compare/v0.35.0...v0.36.0

@@ -7,4 +7,9 @@ import type { OnGetCodeActionsEvent } from '../../interfaces';

private suggestedImports;
/**
* Generic import suggestion function. Shouldn't be called directly from the main loop, but instead called by more specific diagnostic handlers
*/
private suggestImports;
private suggestFunctionImports;
private suggestClassImports;
private addMissingExtends;
}

36

dist/bscPlugin/codeActions/CodeActionsProcessor.js

@@ -7,2 +7,3 @@ "use strict";

const DiagnosticMessages_1 = require("../../DiagnosticMessages");
const parser_1 = require("../../parser");
const util_1 = require("../../util");

@@ -17,4 +18,7 @@ class CodeActionsProcessor {

if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.callToUnknownFunction) {
this.suggestImports(diagnostic);
this.suggestFunctionImports(diagnostic);
}
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.classCouldNotBeFound) {
this.suggestClassImports(diagnostic);
}
else if (diagnostic.code === DiagnosticMessages_1.DiagnosticCodeMap.xmlComponentMissingExtendsAttribute) {

@@ -25,10 +29,12 @@ this.addMissingExtends(diagnostic);

}
suggestImports(diagnostic) {
/**
* Generic import suggestion function. Shouldn't be called directly from the main loop, but instead called by more specific diagnostic handlers
*/
suggestImports(diagnostic, key, files) {
var _a, _b, _c;
const lowerFunctionName = diagnostic.data.functionName.toLowerCase();
//skip generating duplicate suggestions if we've already done this one
if (this.suggestedImports.has(lowerFunctionName)) {
//skip if we already have this suggestion
if (this.suggestedImports.has(key)) {
return;
}
this.suggestedImports.add(lowerFunctionName);
this.suggestedImports.add(key);
const importStatements = this.event.file.parser.references.importStatements;

@@ -38,3 +44,3 @@ //find the position of the first import statement, or the top of the file if there is none

//find all files that reference this function
for (const file of this.event.file.program.findFilesForFunction(lowerFunctionName)) {
for (const file of files) {
const pkgPath = util_1.util.getRokuPkgPath(file.pkgPath);

@@ -55,2 +61,18 @@ this.event.codeActions.push(CodeActionUtil_1.codeActionUtil.createCodeAction({

}
suggestFunctionImports(diagnostic) {
//skip if not a BrighterScript file
if (diagnostic.file.parseMode !== parser_1.ParseMode.BrighterScript) {
return;
}
const lowerFunctionName = diagnostic.data.functionName.toLowerCase();
this.suggestImports(diagnostic, lowerFunctionName, this.event.file.program.findFilesForFunction(lowerFunctionName));
}
suggestClassImports(diagnostic) {
//skip if not a BrighterScript file
if (diagnostic.file.parseMode !== parser_1.ParseMode.BrighterScript) {
return;
}
const lowerClassName = diagnostic.data.className.toLowerCase();
this.suggestImports(diagnostic, lowerClassName, this.event.file.program.findFilesForClass(lowerClassName));
}
addMissingExtends(diagnostic) {

@@ -57,0 +79,0 @@ var _a;

155

dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js

@@ -74,43 +74,120 @@ "use strict";

});
it('does not produce duplicate code actions for bs imports', () => {
//define the function in two files
program.addOrReplaceFile('components/lib1.brs', `
sub doSomething()
end sub
`);
program.addOrReplaceFile('components/lib2.brs', `
sub doSomething()
end sub
`);
//use the function in this file
const componentCommonFile = program.addOrReplaceFile('components/ComponentCommon.bs', `
sub init()
doSomething()
end sub
`);
//import the file in two scopes
program.addOrReplaceFile('components/comp1.xml', testHelpers_spec_1.trim `
<?xml version="1.0" encoding="utf-8" ?>
<component name="ChildScene">
<script uri="ComponentCommon.bs" />
</component>
`);
program.addOrReplaceFile('components/comp2.xml', testHelpers_spec_1.trim `
<?xml version="1.0" encoding="utf-8" ?>
<component name="ChildScene">
<script uri="ComponentCommon.bs" />
</component>
`);
program.validate();
//we should only get each file import suggestion exactly once
const codeActions = program.getCodeActions(componentCommonFile.pathAbsolute,
// doSome|thing()
util_1.util.createRange(2, 22, 2, 22));
chai_1.expect(codeActions.map(x => x.title).sort()).to.eql([
`import "pkg:/components/lib1.brs"`,
`import "pkg:/components/lib2.brs"`
]);
});
it('does not suggest imports for brs files', () => {
//import the file in two scopes
program.addOrReplaceFile('components/comp1.xml', testHelpers_spec_1.trim `
<?xml version="1.0" encoding="utf-8" ?>
<component name="ChildScene">
<script uri="comp1.brs" />
</component>
`);
//import the function here
const file = program.addOrReplaceFile('components/comp1.brs', `
sub init()
DoSomething()
end sub
`);
//define the function here
program.addOrReplaceFile('source/lib.brs', `
sub DoSomething()
end sub
`);
program.validate();
//there should be no code actions since this is a brs file
const codeActions = program.getCodeActions(file.pathAbsolute,
// DoSometh|ing()
util_1.util.createRange(2, 28, 2, 28));
chai_1.expect(codeActions).to.be.empty;
});
it('suggests class imports', () => {
//import the file in two scopes
program.addOrReplaceFile('components/comp1.xml', testHelpers_spec_1.trim `
<?xml version="1.0" encoding="utf-8" ?>
<component name="ChildScene">
<script uri="comp1.bs" />
</component>
`);
const file = program.addOrReplaceFile('components/comp1.bs', `
sub init()
dude = new Person()
end sub
`);
program.addOrReplaceFile('source/Person.bs', `
class Person
end class
`);
program.validate();
chai_1.expect(program.getCodeActions(file.pathAbsolute,
// new Per|son()
util_1.util.createRange(2, 34, 2, 34)).map(x => x.title).sort()).to.eql([
`import "pkg:/source/Person.bs"`
]);
});
it('suggests class imports', () => {
//import the file in two scopes
program.addOrReplaceFile('components/comp1.xml', testHelpers_spec_1.trim `
<?xml version="1.0" encoding="utf-8" ?>
<component name="ChildScene">
<script uri="comp1.bs" />
</component>
`);
//import the function here
const file = program.addOrReplaceFile('components/comp1.bs', `
sub init()
kitty = new Animals.Cat()
end sub
`);
program.addOrReplaceFile('source/Animals.bs', `
namespace Animals
class Cat
end class
end namespace
`);
program.validate();
chai_1.expect(program.getCodeActions(file.pathAbsolute,
// new Anim|als.Cat()
util_1.util.createRange(2, 36, 2, 36)).map(x => x.title).sort()).to.eql([
`import "pkg:/source/Animals.bs"`
]);
});
});
it('does not produce duplicate code actions for bs imports', () => {
//define the function in two files
program.addOrReplaceFile('components/lib1.brs', `
sub doSomething()
end sub
`);
program.addOrReplaceFile('components/lib2.brs', `
sub doSomething()
end sub
`);
//use the function in this file
const componentCommonFile = program.addOrReplaceFile('components/ComponentCommon.bs', `
sub init()
doSomething()
end sub
`);
//import the file in two scopes
program.addOrReplaceFile('components/comp1.xml', testHelpers_spec_1.trim `
<?xml version="1.0" encoding="utf-8" ?>
<component name="ChildScene">
<script uri="ComponentCommon.bs" />
</component>
`);
program.addOrReplaceFile('components/comp2.xml', testHelpers_spec_1.trim `
<?xml version="1.0" encoding="utf-8" ?>
<component name="ChildScene">
<script uri="ComponentCommon.bs" />
</component>
`);
program.validate();
//we should only get each file import suggestion exactly once
const codeActions = program.getCodeActions(componentCommonFile.pathAbsolute,
// doSome|thing()
util_1.util.createRange(2, 22, 2, 22));
chai_1.expect(codeActions.map(x => x.title).sort()).to.eql([
`import "pkg:/components/lib1.brs"`,
`import "pkg:/components/lib2.brs"`
]);
});
});
//# sourceMappingURL=CodeActionsProcessor.spec.js.map

@@ -161,2 +161,5 @@ import type { Position } from 'vscode-languageserver';

severity: 1;
data: {
className: string;
};
};

@@ -163,0 +166,0 @@ expectedClassFieldIdentifier: () => {

@@ -162,3 +162,6 @@ "use strict";

code: 1029,
severity: vscode_languageserver_1.DiagnosticSeverity.Error
severity: vscode_languageserver_1.DiagnosticSeverity.Error,
data: {
className: className
}
}),

@@ -165,0 +168,0 @@ expectedClassFieldIdentifier: () => ({

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -757,3 +763,2 @@ exports.CustomCommands = exports.LanguageServer = void 0;

catch (e) {
this.connection.tracer.log(e);
this.sendCriticalFailure(`Critical error parsing/ validating ${filePath}: ${e.message}`);

@@ -811,3 +816,3 @@ }

async onSignatureHelp(params) {
var _a, _b;
var _a, _b, _c;
await this.waitAllProgramFirstRuns();

@@ -828,3 +833,3 @@ const filepath = util_1.util.uriToPath(params.textDocument.uri);

catch (e) {
this.connection.console.error(`error in onSignatureHelp: ${e.message}${(_b = e.stack) !== null && _b !== void 0 ? _b : ''}`);
this.connection.console.error(`error in onSignatureHelp: ${(_c = (_b = e.stack) !== null && _b !== void 0 ? _b : e.message) !== null && _c !== void 0 ? _c : e}`);
return {

@@ -880,2 +885,50 @@ signatures: [],

}
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onInitialize", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onInitialized", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onCompletion", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onCompletionResolve", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onCodeAction", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onDidChangeConfiguration", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onDidChangeWatchedFiles", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onHover", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onDocumentClose", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "validateTextDocument", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onWorkspaceSymbol", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onDocumentSymbol", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onDefinition", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onSignatureHelp", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onReferences", null);
__decorate([
AddStackToErrorMessage
], LanguageServer.prototype, "onExecuteCommand", null);
exports.LanguageServer = LanguageServer;

@@ -886,2 +939,33 @@ var CustomCommands;

})(CustomCommands = exports.CustomCommands || (exports.CustomCommands = {}));
/**
* Wraps a method. If there's an error (either sync or via a promise),
* this appends the error's stack trace at the end of the error message so that the connection will
*/
function AddStackToErrorMessage(target, propertyKey, descriptor) {
let originalMethod = descriptor.value;
//wrapping the original method
descriptor.value = function value(...args) {
try {
let result = originalMethod.apply(this, args);
//if the result looks like a promise, log if there's a rejection
if (result === null || result === void 0 ? void 0 : result.then) {
return Promise.resolve(result).catch((e) => {
if (e === null || e === void 0 ? void 0 : e.stack) {
e.message = e.stack;
}
return Promise.reject(e);
});
}
else {
return result;
}
}
catch (e) {
if (e === null || e === void 0 ? void 0 : e.stack) {
e.message = e.stack;
}
throw e;
}
};
}
//# sourceMappingURL=LanguageServer.js.map

@@ -851,3 +851,6 @@ "use strict";

}
plus = items.length > 0 ? ' + ' : '';
//set the plus after the first occurance of a nonzero length set of items
if (plus === '' && items.length > 0) {
plus = ' + ';
}
}

@@ -854,0 +857,0 @@ for (let i = 0; i < this.quasis.length; i++) {

@@ -267,2 +267,4 @@ import type { Token } from '../lexer';

classStatements: ClassStatement[];
get classStatementLookup(): Map<string, ClassStatement>;
private _classStatementLookup;
functionExpressions: FunctionExpression[];

@@ -269,0 +271,0 @@ functionStatements: FunctionStatement[];

@@ -143,2 +143,5 @@ "use strict";

});
it('properly transpiles two template strings side-by-side', () => {
testTranspile('a = `${"hello"}${"world"}`', 'a = "hello" + "world"');
});
it('skips calling toString on strings', () => {

@@ -145,0 +148,0 @@ testTranspile(`

@@ -242,2 +242,6 @@ import type { CodeAction, CompletionItem, Position, Range, SignatureInformation } from 'vscode-languageserver';

/**
* Find a list of files in the program that have a function with the given name (case INsensitive)
*/
findFilesForClass(className: string): (BrsFile | XmlFile)[];
/**
* Get a map of the manifest information

@@ -244,0 +248,0 @@ */

@@ -510,2 +510,3 @@ "use strict";

getStatementsForXmlFile(scope, filterName) {
var _a, _b;
let results = new Map();

@@ -517,3 +518,3 @@ const filesSearched = new Set();

while (reflection_1.isXmlScope(currentScope)) {
for (let name of currentScope.xmlFile.ast.component.api.functions.map((f) => f.name)) {
for (let name of (_b = (_a = currentScope.xmlFile.ast.component.api) === null || _a === void 0 ? void 0 : _a.functions.map((f) => f.name)) !== null && _b !== void 0 ? _b : []) {
if (!filterName || name === filterName) {

@@ -1004,2 +1005,20 @@ funcNames.add(name);

/**
* Find a list of files in the program that have a function with the given name (case INsensitive)
*/
findFilesForClass(className) {
const files = [];
const lowerClassName = className.toLowerCase();
//find every file with this class defined
for (const file of Object.values(this.files)) {
if (reflection_1.isBrsFile(file)) {
//TODO handle namespace-relative classes
//if the file has a function with this name
if (file.parser.references.classStatementLookup.get(lowerClassName) !== undefined) {
files.push(file);
}
}
}
return files;
}
/**
* Get a map of the manifest information

@@ -1006,0 +1025,0 @@ */

{
"name": "brighterscript",
"version": "0.35.0",
"version": "0.36.0",
"description": "A superset of Roku's BrightScript language.",

@@ -5,0 +5,0 @@ "scripts": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc