brighterscript
Advanced tools
Comparing version 0.23.0 to 0.23.1
@@ -9,2 +9,10 @@ # Changelog | ||
## [0.23.1] - 2020-12-22 | ||
### Changed | ||
- renamed `Scope.getFiles()` to `Scope.getAllFiles()` and added a new function called `Scope.getOwnFiles()` | ||
### Fixed | ||
- bug preventing `d.bs` loaded in parent files from showing up in child files. ([#252](https://github.com/rokucommunity/brighterscript/pull/252)) | ||
## [0.23.0] - 2020-12-18 | ||
@@ -765,2 +773,5 @@ ### Changed | ||
[0.22.0]: https://github.com/rokucommunity/brighterscript/compare/v0.21.0...v0.22.0 | ||
[0.22.1]: https://github.com/rokucommunity/brighterscript/compare/v0.22.0...v0.22.1 | ||
[0.22.1]: https://github.com/rokucommunity/brighterscript/compare/v0.22.0...v0.22.1 | ||
[0.22.1]: https://github.com/rokucommunity/brighterscript/compare/v0.22.0...v0.22.1 | ||
[0.23.0]: https://github.com/rokucommunity/brighterscript/compare/v0.22.1...v0.23.0 | ||
[0.23.1]: https://github.com/rokucommunity/brighterscript/compare/v0.23.0...v0.23.1 |
@@ -682,3 +682,3 @@ "use strict"; | ||
//include the first part of namespaces | ||
let namespaces = scope.getNamespaceStatements(); | ||
let namespaces = scope.getAllNamespaceStatements(); | ||
for (let stmt of namespaces) { | ||
@@ -1010,3 +1010,3 @@ let firstPart = stmt.nameExpression.getNameParts().shift(); | ||
for (const scope of this.program.getScopesForFile(this)) { | ||
for (const file of scope.getFiles()) { | ||
for (const file of scope.getAllFiles()) { | ||
if (reflection_1.isXmlFile(file) || filesSearched[file.pathAbsolute]) { | ||
@@ -1140,3 +1140,3 @@ continue; | ||
for (const scope of scopes) { | ||
for (const file of scope.getFiles()) { | ||
for (const file of scope.getAllFiles()) { | ||
if (reflection_1.isXmlFile(file)) { | ||
@@ -1143,0 +1143,0 @@ continue; |
@@ -86,2 +86,11 @@ import type { CodeWithSourceMap } from 'source-map'; | ||
/** | ||
* List of all pkgPaths to scripts that this XmlFile depends, regardless of whether they are loaded in the program or not. | ||
* This includes own dependencies and all parent compoent dependencies | ||
* coming from: | ||
* - script tags | ||
* - implied codebehind file | ||
* - import statements from imported scripts or their descendents | ||
*/ | ||
getAllDependencies(): string[]; | ||
/** | ||
* List of all pkgPaths to scripts that this XmlFile depends on directly, regardless of whether they are loaded in the program or not. | ||
@@ -94,3 +103,3 @@ * This does not account for parent component scripts | ||
*/ | ||
getAllDependencies(): string[]; | ||
getOwnDependencies(): string[]; | ||
/** | ||
@@ -97,0 +106,0 @@ * List of all pkgPaths to scripts that this XmlFile depends on that are actually loaded into the program. |
@@ -56,2 +56,16 @@ "use strict"; | ||
/** | ||
* List of all pkgPaths to scripts that this XmlFile depends, regardless of whether they are loaded in the program or not. | ||
* This includes own dependencies and all parent compoent dependencies | ||
* coming from: | ||
* - script tags | ||
* - implied codebehind file | ||
* - import statements from imported scripts or their descendents | ||
*/ | ||
getAllDependencies() { | ||
return this.cache.getOrAdd(`allScriptImports`, () => { | ||
const value = this.program.dependencyGraph.getAllDependencies(this.dependencyGraphKey); | ||
return value; | ||
}); | ||
} | ||
/** | ||
* List of all pkgPaths to scripts that this XmlFile depends on directly, regardless of whether they are loaded in the program or not. | ||
@@ -64,5 +78,5 @@ * This does not account for parent component scripts | ||
*/ | ||
getAllDependencies() { | ||
getOwnDependencies() { | ||
return this.cache.getOrAdd(`allScriptImports`, () => { | ||
let value = this.program.dependencyGraph.getAllDependencies(this.dependencyGraphKey, [this.parentComponentDependencyGraphKey]); | ||
const value = this.program.dependencyGraph.getAllDependencies(this.dependencyGraphKey, [this.parentComponentDependencyGraphKey]); | ||
return value; | ||
@@ -81,3 +95,3 @@ }); | ||
return this.cache.getOrAdd('allAvailableScriptImports', () => { | ||
let allDependencies = this.getAllDependencies() | ||
let allDependencies = this.getOwnDependencies() | ||
//skip typedef files | ||
@@ -289,3 +303,3 @@ .filter(x => util_1.default.getExtension(x) !== '.d.bs'); | ||
} | ||
let allDependencies = this.getAllDependencies(); | ||
let allDependencies = this.getOwnDependencies(); | ||
for (let importPkgPath of allDependencies) { | ||
@@ -292,0 +306,0 @@ if (importPkgPath.toLowerCase() === file.pkgPath.toLowerCase()) { |
@@ -298,3 +298,3 @@ "use strict"; | ||
`); | ||
chai_1.expect(file.getAllDependencies().sort()).to.eql([ | ||
chai_1.expect(file.getOwnDependencies().sort()).to.eql([ | ||
util_1.standardizePath `source/lib.brs`, | ||
@@ -523,2 +523,51 @@ util_1.standardizePath `source/lib.d.bs` | ||
describe('typedef', () => { | ||
it('loads d.bs files from parent scope', async () => { | ||
var _a; | ||
await program.addOrReplaceFile('components/ParentComponent.xml', ` | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<component name="ParentComponent" extends="Scene"> | ||
<script uri="ParentComponent.brs" /> | ||
</component> | ||
`); | ||
await program.addOrReplaceFile('components/ParentComponent.d.bs', ` | ||
import "Lib.brs" | ||
namespace Parent | ||
sub log() | ||
end sub | ||
end namespace | ||
`); | ||
await program.addOrReplaceFile('components/ParentComponent.brs', ` | ||
sub Parent_log() | ||
end sub | ||
`); | ||
await program.addOrReplaceFile('components/Lib.d.bs', ` | ||
namespace Lib | ||
sub log() | ||
end sub | ||
end namespace | ||
`); | ||
await program.addOrReplaceFile('components/Lib.brs', ` | ||
sub Lib_log() | ||
end sub | ||
`); | ||
await program.addOrReplaceFile('components/ChildComponent.xml', ` | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<component name="ChildComponent" extends="ParentComponent"> | ||
<script uri="ChildComponent.bs" /> | ||
</component> | ||
`); | ||
await program.addOrReplaceFile('components/ChildComponent.bs', ` | ||
sub init() | ||
Parent.log() | ||
Lib.log() | ||
end sub | ||
`); | ||
await program.validate(); | ||
chai_1.expect((_a = program.getDiagnostics()[0]) === null || _a === void 0 ? void 0 : _a.message).not.to.exist; | ||
const scope = program.getComponentScope('ChildComponent'); | ||
chai_1.expect(Object.keys(scope.namespaceLookup).sort()).to.eql([ | ||
'lib', | ||
'parent' | ||
]); | ||
}); | ||
it('loads `d.bs` files into scope', async () => { | ||
@@ -525,0 +574,0 @@ const xmlFile = await program.addOrReplaceFile('components/Component1.xml', ` |
@@ -80,3 +80,3 @@ "use strict"; | ||
//hardcode the files list for global scope to only contain the global file | ||
this.globalScope.getFiles = () => [globalCallables_1.globalFile]; | ||
this.globalScope.getAllFiles = () => [globalCallables_1.globalFile]; | ||
this.globalScope.validate(); | ||
@@ -574,3 +574,4 @@ //for now, disable validation of global scope because the global files have some duplicate method declarations | ||
for (const scope of scopes) { | ||
for (const file of scope.getFiles()) { | ||
const files = scope.getOwnFiles(); | ||
for (const file of files) { | ||
if (reflection_1.isXmlFile(file)) { | ||
@@ -577,0 +578,0 @@ continue; |
@@ -63,5 +63,13 @@ import type { CompletionItem, Position, Range } from 'vscode-languageserver'; | ||
getFile(pathAbsolute: string): BscFile; | ||
getFiles(): BscFile[]; | ||
get fileCount(): number; | ||
/** | ||
* Get the list of files referenced by this scope that are actually loaded in the program. | ||
* Excludes files from ancestor scopes | ||
*/ | ||
getOwnFiles(): BscFile[]; | ||
/** | ||
* Get the list of files referenced by this scope that are actually loaded in the program. | ||
* Includes files from this scope and all ancestor scopes | ||
*/ | ||
getAllFiles(): BscFile[]; | ||
/** | ||
* Get the list of errors for this scope. It's calculated on the fly, so | ||
@@ -82,4 +90,11 @@ * call this sparingly. | ||
getCallableByName(name: string): import("./interfaces").Callable; | ||
enumerateFiles(callback: (file: BscFile) => void): void; | ||
/** | ||
* Call a function for each file directly included in this scope (including files found only in parent scopes). | ||
*/ | ||
enumerateAllFiles(callback: (file: BscFile) => void): void; | ||
/** | ||
* Call a function for each file directly included in this scope (excluding files found only in parent scopes). | ||
*/ | ||
enumerateOwnFiles(callback: (file: BscFile) => void): void; | ||
/** | ||
* Get the list of callables explicitly defined in files in this scope. | ||
@@ -93,3 +108,3 @@ * This excludes ancestor callables | ||
buildNamespaceLookup(): Record<string, NamespaceContainer>; | ||
getNamespaceStatements(): NamespaceStatement[]; | ||
getAllNamespaceStatements(): NamespaceStatement[]; | ||
protected logDebug(...args: any[]): void; | ||
@@ -135,3 +150,3 @@ private _debugLogComponentName; | ||
*/ | ||
private getScriptImports; | ||
private getOwnScriptImports; | ||
/** | ||
@@ -147,3 +162,3 @@ * Verify that all of the scripts imported by each file in this scope actually exist | ||
/** | ||
* Determine if this scope is referenced and known by the file. | ||
* Determine if this file is included in this scope (excluding parent scopes) | ||
* @param file | ||
@@ -150,0 +165,0 @@ */ |
@@ -58,3 +58,3 @@ "use strict"; | ||
const map = new Map(); | ||
this.enumerateFiles((file) => { | ||
this.enumerateAllFiles((file) => { | ||
var _a; | ||
@@ -90,3 +90,4 @@ for (let cls of file.parser.references.classStatements) { | ||
let namespaceNameLower = namespaceName.toLowerCase(); | ||
this.enumerateFiles((file) => { | ||
//TODO refactor to use this.namespaceLookup | ||
this.enumerateAllFiles((file) => { | ||
for (let namespace of file.parser.references.namespaceStatements) { | ||
@@ -125,3 +126,3 @@ let loopNamespaceNameLower = namespace.name.toLowerCase(); | ||
pathAbsolute = util_1.standardizePath `${pathAbsolute}`; | ||
let files = this.getFiles(); | ||
let files = this.getAllFiles(); | ||
for (let file of files) { | ||
@@ -133,23 +134,37 @@ if (file.pathAbsolute === pathAbsolute) { | ||
} | ||
getFiles() { | ||
return this.cache.getOrAdd('files', () => { | ||
/** | ||
* Get the list of files referenced by this scope that are actually loaded in the program. | ||
* Excludes files from ancestor scopes | ||
*/ | ||
getOwnFiles() { | ||
//source scope only inherits files from global, so just return all files. This function mostly exists to assist XmlScope | ||
return this.getAllFiles(); | ||
} | ||
/** | ||
* Get the list of files referenced by this scope that are actually loaded in the program. | ||
* Includes files from this scope and all ancestor scopes | ||
*/ | ||
getAllFiles() { | ||
return this.cache.getOrAdd('getAllFiles', () => { | ||
let result = []; | ||
let dependencies = this.program.dependencyGraph.getAllDependencies(this.dependencyGraphKey); | ||
for (let dependency of dependencies) { | ||
//skip scopes and components | ||
//load components by their name | ||
if (dependency.startsWith('component:')) { | ||
continue; | ||
let comp = this.program.getComponent(dependency.replace(/$component:/, '')); | ||
if (comp) { | ||
result.push(comp.file); | ||
} | ||
} | ||
let file = this.program.getFileByPkgPath(dependency); | ||
if (file) { | ||
result.push(file); | ||
else { | ||
let file = this.program.getFileByPkgPath(dependency); | ||
if (file) { | ||
result.push(file); | ||
} | ||
} | ||
} | ||
this.logDebug('getFiles', () => result.map(x => x.pkgPath)); | ||
this.logDebug('getAllFiles', () => result.map(x => x.pkgPath)); | ||
return result; | ||
}); | ||
} | ||
get fileCount() { | ||
return Object.keys(this.getFiles()).length; | ||
} | ||
/** | ||
@@ -162,3 +177,3 @@ * Get the list of errors for this scope. It's calculated on the fly, so | ||
//add diagnostics from every referenced file | ||
this.enumerateFiles((file) => { | ||
this.enumerateOwnFiles((file) => { | ||
diagnosticLists.push(file.getDiagnostics()); | ||
@@ -203,4 +218,7 @@ }); | ||
} | ||
enumerateFiles(callback) { | ||
const files = this.getFiles(); | ||
/** | ||
* Call a function for each file directly included in this scope (including files found only in parent scopes). | ||
*/ | ||
enumerateAllFiles(callback) { | ||
const files = this.getAllFiles(); | ||
for (const file of files) { | ||
@@ -215,2 +233,15 @@ //skip files that have a typedef | ||
/** | ||
* Call a function for each file directly included in this scope (excluding files found only in parent scopes). | ||
*/ | ||
enumerateOwnFiles(callback) { | ||
const files = this.getOwnFiles(); | ||
for (const file of files) { | ||
//skip files that have a typedef | ||
if (file.hasTypedef) { | ||
continue; | ||
} | ||
callback(file); | ||
} | ||
} | ||
/** | ||
* Get the list of callables explicitly defined in files in this scope. | ||
@@ -221,5 +252,5 @@ * This excludes ancestor callables | ||
let result = []; | ||
this.logDebug('getOwnCallables() files: ', () => this.getFiles().map(x => x.pkgPath)); | ||
this.logDebug('getOwnCallables() files: ', () => this.getOwnFiles().map(x => x.pkgPath)); | ||
//get callables from own files | ||
this.enumerateFiles((file) => { | ||
this.enumerateOwnFiles((file) => { | ||
for (let callable of file.callables) { | ||
@@ -239,3 +270,3 @@ result.push({ | ||
let namespaceLookup = {}; | ||
this.enumerateFiles((file) => { | ||
this.enumerateAllFiles((file) => { | ||
var _a; | ||
@@ -288,5 +319,5 @@ for (let namespace of file.parser.references.namespaceStatements) { | ||
} | ||
getNamespaceStatements() { | ||
getAllNamespaceStatements() { | ||
let result = []; | ||
this.enumerateFiles((file) => { | ||
this.enumerateAllFiles((file) => { | ||
result.push(...file.parser.references.namespaceStatements); | ||
@@ -325,3 +356,3 @@ }); | ||
let callableContainerMap = util_1.util.getCallableContainersByLowerName(callables); | ||
let files = this.getFiles(); | ||
let files = this.getOwnFiles(); | ||
this.program.plugins.emit('beforeScopeValidate', this, files, callableContainerMap); | ||
@@ -335,3 +366,3 @@ //find all duplicate function declarations | ||
//do many per-file checks | ||
this.enumerateFiles((file) => { | ||
this.enumerateOwnFiles((file) => { | ||
this.diagnosticDetectCallsToUnknownFunctions(file, callableContainerMap); | ||
@@ -404,3 +435,3 @@ this.diagnosticDetectFunctionCallsWithWrongParamCount(file, callableContainerMap); | ||
let result = []; | ||
this.enumerateFiles((file) => { | ||
this.enumerateOwnFiles((file) => { | ||
let expressions = file.parser.references.newExpressions; | ||
@@ -582,5 +613,5 @@ for (let expression of expressions) { | ||
*/ | ||
getScriptImports() { | ||
getOwnScriptImports() { | ||
let result = []; | ||
this.enumerateFiles((file) => { | ||
this.enumerateOwnFiles((file) => { | ||
if (reflection_1.isBrsFile(file)) { | ||
@@ -599,3 +630,3 @@ result.push(...file.ownScriptImports); | ||
diagnosticValidateScriptImportPaths() { | ||
let scriptImports = this.getScriptImports(); | ||
let scriptImports = this.getOwnScriptImports(); | ||
//verify every script import | ||
@@ -626,3 +657,3 @@ for (let scriptImport of scriptImports) { | ||
getFileByRelativePath(relativePath) { | ||
let files = this.getFiles(); | ||
let files = this.getAllFiles(); | ||
for (let file of files) { | ||
@@ -635,7 +666,7 @@ if (file.pkgPath.toLowerCase() === relativePath.toLowerCase()) { | ||
/** | ||
* Determine if this scope is referenced and known by the file. | ||
* Determine if this file is included in this scope (excluding parent scopes) | ||
* @param file | ||
*/ | ||
hasFile(file) { | ||
let files = this.getFiles(); | ||
let files = this.getOwnFiles(); | ||
let hasFile = files.includes(file); | ||
@@ -676,3 +707,3 @@ return hasFile; | ||
let results = []; | ||
this.enumerateFiles((file) => { | ||
this.enumerateAllFiles((file) => { | ||
results.push(...file.propertyNameCompletions); | ||
@@ -679,0 +710,0 @@ }); |
@@ -41,5 +41,4 @@ "use strict"; | ||
verifyNewExpressions() { | ||
var _a, _b; | ||
let files = this.scope.getFiles(); | ||
for (let file of files) { | ||
this.scope.enumerateOwnFiles((file) => { | ||
var _a, _b; | ||
let newExpressions = file.parser.references.newExpressions; | ||
@@ -63,3 +62,3 @@ for (let newExpression of newExpressions) { | ||
} | ||
} | ||
}); | ||
} | ||
@@ -187,6 +186,5 @@ findNamespaceNonNamespaceCollisions() { | ||
findClasses() { | ||
var _a; | ||
this.classes = {}; | ||
let files = this.scope.getFiles(); | ||
for (let file of files) { | ||
this.scope.enumerateAllFiles((file) => { | ||
var _a; | ||
for (let x of (_a = file.parser.references.classStatements) !== null && _a !== void 0 ? _a : []) { | ||
@@ -215,3 +213,3 @@ let classStatement = x; | ||
} | ||
} | ||
}); | ||
} | ||
@@ -218,0 +216,0 @@ linkClassesWithParents() { |
@@ -20,2 +20,3 @@ import type { Location, Position } from 'vscode-languageserver'; | ||
private diagnosticDetectDuplicateAncestorScriptImports; | ||
getAllFiles(): BscFile[]; | ||
/** | ||
@@ -25,3 +26,3 @@ * Get the list of files referenced by this scope that are actually loaded in the program. | ||
*/ | ||
getFiles(): BscFile[]; | ||
getOwnFiles(): BscFile[]; | ||
/** | ||
@@ -28,0 +29,0 @@ * Get the definition (where was this thing first defined) of the symbol under the position |
@@ -66,2 +66,9 @@ "use strict"; | ||
} | ||
getAllFiles() { | ||
return this.cache.getOrAdd('getAllFiles-xmlScope', () => { | ||
const allFiles = super.getAllFiles(); | ||
allFiles.push(this.xmlFile); | ||
return allFiles; | ||
}); | ||
} | ||
/** | ||
@@ -71,8 +78,8 @@ * Get the list of files referenced by this scope that are actually loaded in the program. | ||
*/ | ||
getFiles() { | ||
return this.cache.getOrAdd('files', () => { | ||
getOwnFiles() { | ||
return this.cache.getOrAdd('getOwnFiles', () => { | ||
let result = [ | ||
this.xmlFile | ||
]; | ||
let scriptPkgPaths = this.xmlFile.getAllDependencies(); | ||
let scriptPkgPaths = this.xmlFile.getOwnDependencies(); | ||
for (let scriptPkgPath of scriptPkgPaths) { | ||
@@ -79,0 +86,0 @@ let file = this.program.getFileByPkgPath(scriptPkgPath); |
{ | ||
"name": "brighterscript", | ||
"version": "0.23.0", | ||
"version": "0.23.1", | ||
"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 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 not supported yet
2363199
33649