From cc21c6d3c72375c9233f374393a8cda49b6b5934 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Fri, 26 Jan 2024 10:17:37 -0500 Subject: [PATCH] Upgrade to bsc 1.0.0-alpha.25 --- package-lock.json | 20 +++++++------- package.json | 4 +-- src/plugins/checkUsage/index.ts | 29 +++++++++++++++------ src/plugins/codeStyle/index.ts | 12 ++++----- src/plugins/codeStyle/styleFixes.ts | 4 +-- src/plugins/trackCodeFlow/index.ts | 6 ++--- src/plugins/trackCodeFlow/returnTracking.ts | 4 +-- src/plugins/trackCodeFlow/trackFixes.ts | 4 +-- src/plugins/trackCodeFlow/varTracking.ts | 12 ++++----- src/testHelpers.spec.ts | 4 +-- src/textEdit.ts | 4 +-- src/util.ts | 10 +++---- 12 files changed, 62 insertions(+), 51 deletions(-) diff --git a/package-lock.json b/package-lock.json index 85d4b13..01d7e4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/node": "^14.6.0", "@typescript-eslint/eslint-plugin": "^3.10.1", "@typescript-eslint/parser": "^3.10.1", - "brighterscript": "^0.66.0-alpha.6", + "brighterscript": "^1.0.0-alpha.25", "chai": "^4.3.6", "coveralls": "^3.1.1", "eslint": "^7.7.0", @@ -38,7 +38,7 @@ "typescript": "^4.9.4" }, "peerDependencies": { - "brighterscript": ">= 0.66.0-alpha.6 < 1" + "brighterscript": "^1.0.0-alpha.25" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1208,9 +1208,9 @@ } }, "node_modules/brighterscript": { - "version": "0.66.0-alpha.11", - "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.66.0-alpha.11.tgz", - "integrity": "sha512-ThTwHI1CzczkW6A8NkHbXl4dXXOyzY2yqoeYul/V3m/iIrsrqTq5Oy+sWm392kIDYigXPNuPprvxni8FuDGykg==", + "version": "1.0.0-alpha.25", + "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-1.0.0-alpha.25.tgz", + "integrity": "sha512-4+shSLjMLOGHd2l1MqwAwedngwDXNY1u9+9xitXLG1jR+QUukSgd9LneKjkn4PrE2urFwtpHMcan6q5ASXoQkg==", "dev": true, "dependencies": { "@rokucommunity/bslib": "^0.1.1", @@ -1236,7 +1236,7 @@ "parse-ms": "^2.1.0", "readline": "^1.3.0", "require-relative": "^0.8.7", - "roku-deploy": "^3.11.1", + "roku-deploy": "^3.11.2", "serialize-error": "^7.0.1", "source-map": "^0.7.4", "uuid": "^9.0.0", @@ -6490,9 +6490,9 @@ } }, "brighterscript": { - "version": "0.66.0-alpha.11", - "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.66.0-alpha.11.tgz", - "integrity": "sha512-ThTwHI1CzczkW6A8NkHbXl4dXXOyzY2yqoeYul/V3m/iIrsrqTq5Oy+sWm392kIDYigXPNuPprvxni8FuDGykg==", + "version": "1.0.0-alpha.25", + "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-1.0.0-alpha.25.tgz", + "integrity": "sha512-4+shSLjMLOGHd2l1MqwAwedngwDXNY1u9+9xitXLG1jR+QUukSgd9LneKjkn4PrE2urFwtpHMcan6q5ASXoQkg==", "dev": true, "requires": { "@rokucommunity/bslib": "^0.1.1", @@ -6518,7 +6518,7 @@ "parse-ms": "^2.1.0", "readline": "^1.3.0", "require-relative": "^0.8.7", - "roku-deploy": "^3.11.1", + "roku-deploy": "^3.11.2", "serialize-error": "^7.0.1", "source-map": "^0.7.4", "uuid": "^9.0.0", diff --git a/package.json b/package.json index 2325cca..9ad1efe 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@types/node": "^14.6.0", "@typescript-eslint/eslint-plugin": "^3.10.1", "@typescript-eslint/parser": "^3.10.1", - "brighterscript": "^0.66.0-alpha.6", + "brighterscript": "^1.0.0-alpha.25", "chai": "^4.3.6", "coveralls": "^3.1.1", "eslint": "^7.7.0", @@ -60,7 +60,7 @@ "typescript": "^4.9.4" }, "peerDependencies": { - "brighterscript": ">= 0.66.0-alpha.6 < 1" + "brighterscript": "^1.0.0-alpha.25" }, "mocha": { "spec": "src/**/*.spec.ts", diff --git a/src/plugins/checkUsage/index.ts b/src/plugins/checkUsage/index.ts index edb3149..a9db077 100644 --- a/src/plugins/checkUsage/index.ts +++ b/src/plugins/checkUsage/index.ts @@ -1,4 +1,4 @@ -import { AfterFileValidateEvent, AfterProgramValidateEvent, AfterScopeValidateEvent, File, CompilerPlugin, createVisitor, DiagnosticSeverity, isBrsFile, isXmlFile, Range, TokenKind, WalkMode, XmlFile } from 'brighterscript'; +import { AfterFileValidateEvent, AfterProgramValidateEvent, AfterScopeValidateEvent, CompilerPlugin, createVisitor, DiagnosticSeverity, isBrsFile, isXmlFile, Range, TokenKind, WalkMode, XmlFile, FunctionExpression, BscFile, isFunctionExpression, Cache } from 'brighterscript'; import { SGNode } from 'brighterscript/dist/parser/SGTypes'; import { PluginContext } from '../../util'; @@ -37,7 +37,7 @@ export default class CheckUsage implements CompilerPlugin { this.walked = walked; } - private walkChildren(v: Vertice, children: SGNode[], file: File) { + private walkChildren(v: Vertice, children: SGNode[], file: BscFile) { children.forEach(node => { const name = node.tagName; if (name) { @@ -108,6 +108,12 @@ export default class CheckUsage implements CompilerPlugin { } } + private functionExpressionCache = new Cache(); + + beforeProgramValidate() { + this.functionExpressionCache.clear(); + } + afterScopeValidate(event: AfterScopeValidateEvent) { const { scope } = event; const files = scope.getAllFiles(); @@ -159,9 +165,16 @@ export default class CheckUsage implements CompilerPlugin { if (pkgPath === 'source/main.brs' || pkgPath === 'source/main.bs') { this.main = fv; } + + // look up all function expressions exactly 1 time for this file, even if it's used across many scopes + const functionExpressions = this.functionExpressionCache.getOrAdd(file, () => { + return file.parser.ast.findChildren(isFunctionExpression, { walkMode: WalkMode.visitExpressionsRecursive }); + }); + + // find strings that look like referring to component names - file.parser.references.functionExpressions.forEach(fun => { - fun.body.walk(createVisitor({ + for (const func of functionExpressions) { + func.body.walk(createVisitor({ LiteralExpression: (e) => { const { kind } = e.token; if (kind === TokenKind.StringLiteral) { @@ -179,7 +192,7 @@ export default class CheckUsage implements CompilerPlugin { } } }), { walkMode: WalkMode.visitExpressions }); - }); + } }); } @@ -220,7 +233,7 @@ function normalizePath(s: string) { return p; } -function createComponentEdge(name: string, range: Range = null, file: File = null) { +function createComponentEdge(name: string, range: Range = null, file: BscFile = null) { return { name: `"${name.toLowerCase()}"`, range, @@ -230,13 +243,13 @@ function createComponentEdge(name: string, range: Range = null, file: File = nul interface Vertice { name: string; - file: File; + file: BscFile; edges: Edge[]; used?: boolean; } interface Edge { name: string; - file?: File; + file?: BscFile; range?: Range; } diff --git a/src/plugins/codeStyle/index.ts b/src/plugins/codeStyle/index.ts index 2d7c9f0..cf11c9a 100644 --- a/src/plugins/codeStyle/index.ts +++ b/src/plugins/codeStyle/index.ts @@ -39,7 +39,6 @@ export default class CodeStyle implements CompilerPlugin { const validateCondition = conditionStyle !== 'off'; const requireConditionGroup = conditionStyle === 'group'; const validateAAStyle = aaCommaStyle !== 'off'; - const walkExpressions = validateAAStyle || validateColorFormat; const validateEolLast = eolLast !== 'off'; const disallowEolLast = eolLast === 'never'; const validateColorStyle = validateColorFormat ? createColorValidator(severity) : undefined; @@ -85,6 +84,10 @@ export default class CodeStyle implements CompilerPlugin { } file.ast.walk(createVisitor({ + // validate function style (`function` or `sub`) + FunctionExpression: (func) => { + this.validateFunctionStyle(func, diagnostics); + }, IfStatement: s => { const hasThenToken = !!s.tokens.then; if (!s.isInline && validateBlockIf) { @@ -157,12 +160,7 @@ export default class CodeStyle implements CompilerPlugin { diagnostics.push(messages.noStop(s.tokens.stop.range, noStop)); } } - }), { walkMode: walkExpressions ? WalkMode.visitAllRecursive : WalkMode.visitStatementsRecursive }); - - // validate function style (`function` or `sub`) - for (const fun of file.parser.references.functionExpressions) { - this.validateFunctionStyle(fun, diagnostics); - } + }), { walkMode: WalkMode.visitAllRecursive }); // add file reference let bsDiagnostics: BsDiagnostic[] = diagnostics.map(diagnostic => ({ diff --git a/src/plugins/codeStyle/styleFixes.ts b/src/plugins/codeStyle/styleFixes.ts index 8dea0e1..e76a0ac 100644 --- a/src/plugins/codeStyle/styleFixes.ts +++ b/src/plugins/codeStyle/styleFixes.ts @@ -1,10 +1,10 @@ -import { File, BsDiagnostic, FunctionExpression, GroupingExpression, IfStatement, isIfStatement, isVoidType, Position, Range, SymbolTypeFlag, VoidType, WhileStatement } from 'brighterscript'; +import { BscFile, BsDiagnostic, FunctionExpression, GroupingExpression, IfStatement, isIfStatement, isVoidType, Position, Range, SymbolTypeFlag, VoidType, WhileStatement } from 'brighterscript'; import { ChangeEntry, comparePos, insertText, replaceText } from '../../textEdit'; import { CodeStyleError } from './diagnosticMessages'; import { platform } from 'process'; export function extractFixes( - addFixes: (file: File, changes: ChangeEntry) => void, + addFixes: (file: BscFile, changes: ChangeEntry) => void, diagnostics: BsDiagnostic[] ): BsDiagnostic[] { return diagnostics.filter(diagnostic => { diff --git a/src/plugins/trackCodeFlow/index.ts b/src/plugins/trackCodeFlow/index.ts index 0970a17..9301b95 100644 --- a/src/plugins/trackCodeFlow/index.ts +++ b/src/plugins/trackCodeFlow/index.ts @@ -1,4 +1,4 @@ -import { BsDiagnostic, BrsFile, OnGetCodeActionsEvent, Statement, EmptyStatement, FunctionExpression, isForEachStatement, isForStatement, isIfStatement, isWhileStatement, Range, createStackedVisitor, isBrsFile, isStatement, isExpression, WalkMode, isTryCatchStatement, isCatchStatement, CompilerPlugin, AfterScopeValidateEvent, AfterFileValidateEvent, util } from 'brighterscript'; +import { BsDiagnostic, BrsFile, OnGetCodeActionsEvent, Statement, EmptyStatement, FunctionExpression, isForEachStatement, isForStatement, isIfStatement, isWhileStatement, Range, createStackedVisitor, isBrsFile, isStatement, isExpression, WalkMode, isTryCatchStatement, isCatchStatement, CompilerPlugin, AfterScopeValidateEvent, AfterFileValidateEvent, util, isFunctionExpression } from 'brighterscript'; import { PluginContext } from '../../util'; import { createReturnLinter } from './returnTracking'; import { createVarLinter, resetVarContext, runDeferredValidation } from './varTracking'; @@ -78,7 +78,7 @@ export default class TrackCodeFlow implements CompilerPlugin { resetVarContext(file); - file.parser.references.functionExpressions.forEach((fun) => { + for (const fun of file.parser.ast.findChildren(isFunctionExpression, { walkMode: WalkMode.visitExpressionsRecursive })) { const state: LintState = { file: file, fun: fun, @@ -170,7 +170,7 @@ export default class TrackCodeFlow implements CompilerPlugin { varLinter.closeBlock(block); } } - }); + } if (this.lintContext.fix) { diagnostics = extractFixes(this.lintContext.addFixes, diagnostics); diff --git a/src/plugins/trackCodeFlow/returnTracking.ts b/src/plugins/trackCodeFlow/returnTracking.ts index 83f2ead..c2181fe 100644 --- a/src/plugins/trackCodeFlow/returnTracking.ts +++ b/src/plugins/trackCodeFlow/returnTracking.ts @@ -1,4 +1,4 @@ -import { File, FunctionExpression, BsDiagnostic, isCommentStatement, DiagnosticTag, isReturnStatement, isIfStatement, isThrowStatement, TokenKind, util, ReturnStatement, ThrowStatement, isTryCatchStatement, isCatchStatement, isVoidType, SymbolTypeFlag } from 'brighterscript'; +import { BscFile, FunctionExpression, BsDiagnostic, isCommentStatement, DiagnosticTag, isReturnStatement, isIfStatement, isThrowStatement, TokenKind, util, ReturnStatement, ThrowStatement, isTryCatchStatement, isCatchStatement, isVoidType, SymbolTypeFlag } from 'brighterscript'; import { LintState, StatementInfo } from '.'; import { PluginContext } from '../../util'; @@ -23,7 +23,7 @@ enum ReturnLintError { export function createReturnLinter( lintContext: PluginContext, - file: File, + file: BscFile, fun: FunctionExpression, state: LintState, diagnostics: BsDiagnostic[] diff --git a/src/plugins/trackCodeFlow/trackFixes.ts b/src/plugins/trackCodeFlow/trackFixes.ts index 9a711db..83848c9 100644 --- a/src/plugins/trackCodeFlow/trackFixes.ts +++ b/src/plugins/trackCodeFlow/trackFixes.ts @@ -1,9 +1,9 @@ -import { File, BsDiagnostic, Range } from 'brighterscript'; +import { BscFile, BsDiagnostic, Range } from 'brighterscript'; import { ChangeEntry, replaceText } from '../../textEdit'; import { VarLintError } from './varTracking'; export function extractFixes( - addFixes: (file: File, changes: ChangeEntry) => void, + addFixes: (file: BscFile, changes: ChangeEntry) => void, diagnostics: BsDiagnostic[] ): BsDiagnostic[] { return diagnostics.filter(diagnostic => { diff --git a/src/plugins/trackCodeFlow/varTracking.ts b/src/plugins/trackCodeFlow/varTracking.ts index 1089877..91b430d 100644 --- a/src/plugins/trackCodeFlow/varTracking.ts +++ b/src/plugins/trackCodeFlow/varTracking.ts @@ -1,4 +1,4 @@ -import { File, FunctionExpression, BsDiagnostic, Range, isForStatement, isForEachStatement, isIfStatement, isAssignmentStatement, isNamespaceStatement, NamespaceStatement, Expression, isVariableExpression, isBinaryExpression, TokenKind, Scope, CallableContainerMap, DiagnosticSeverity, isLiteralInvalid, isWhileStatement, isCatchStatement, isLabelStatement, isGotoStatement, ParseMode, util, isMethodStatement, isTryCatchStatement } from 'brighterscript'; +import { BscFile, FunctionExpression, BsDiagnostic, Range, isForStatement, isForEachStatement, isIfStatement, isAssignmentStatement, isNamespaceStatement, NamespaceStatement, Expression, isVariableExpression, isBinaryExpression, TokenKind, Scope, CallableContainerMap, DiagnosticSeverity, isLiteralInvalid, isWhileStatement, isCatchStatement, isLabelStatement, isGotoStatement, ParseMode, util, isMethodStatement, isTryCatchStatement } from 'brighterscript'; import { LintState, StatementInfo, NarrowingInfo, VarInfo, VarRestriction } from '.'; import { PluginContext } from '../../util'; @@ -26,17 +26,17 @@ interface ValidationInfo { const deferredValidation: Map = new Map(); -function getDeferred(file: File) { +function getDeferred(file: BscFile) { return deferredValidation.get(file.srcPath); } -export function resetVarContext(file: File) { +export function resetVarContext(file: BscFile) { deferredValidation.set(file.srcPath, []); } export function createVarLinter( lintContext: PluginContext, - file: File, + file: BscFile, fun: FunctionExpression, state: LintState, diagnostics: BsDiagnostic[] @@ -376,7 +376,7 @@ export function createVarLinter( export function runDeferredValidation( lintContext: PluginContext, scope: Scope, - files: File[], + files: BscFile[], callables: CallableContainerMap ) { const topLevelVars = buildTopLevelVars(scope, lintContext.globals); @@ -415,7 +415,7 @@ function buildTopLevelVars(scope: Scope, globals: string[]) { function deferredVarLinter( scope: Scope, - file: File, + file: BscFile, callables: CallableContainerMap, toplevel: Set, deferred: ValidationInfo[], diff --git a/src/testHelpers.spec.ts b/src/testHelpers.spec.ts index 8f6b55e..563e441 100644 --- a/src/testHelpers.spec.ts +++ b/src/testHelpers.spec.ts @@ -1,4 +1,4 @@ -import { BsDiagnostic, File, DiagnosticSeverity, DiagnosticTag, Range } from 'brighterscript'; +import { BsDiagnostic, BscFile, DiagnosticSeverity, DiagnosticTag, Range } from 'brighterscript'; import { CodeDescription, DiagnosticRelatedInformation, Diagnostic } from 'vscode-languageserver-types'; import { expect } from 'chai'; import { firstBy } from 'thenby'; @@ -50,7 +50,7 @@ interface PartialDiagnostic { tags?: Partial[]; relatedInformation?: Partial[]; data?: unknown; - file?: Partial; + file?: Partial; } /** diff --git a/src/textEdit.ts b/src/textEdit.ts index 4683995..8389d40 100644 --- a/src/textEdit.ts +++ b/src/textEdit.ts @@ -1,6 +1,6 @@ import { existsSync } from 'fs'; import { readFile, writeFile } from 'fs-extra'; -import { File, BsDiagnostic, OnGetCodeActionsEvent, Position, Range } from 'brighterscript'; +import { BscFile, BsDiagnostic, OnGetCodeActionsEvent, Position, Range } from 'brighterscript'; import { CodeActionKind, codeActionUtil } from 'brighterscript/dist/CodeActionUtil'; interface LintCodeAction { @@ -125,7 +125,7 @@ export async function applyFixes(fix: boolean, pendingFixes: Map { + return (file: BscFile, entry: ChangeEntry) => { const changes: LintCodeAction[] = entry.changes.map(change => ({ type: 'replace', filePath: file.srcPath, diff --git a/src/util.ts b/src/util.ts index 640c61c..bc196b5 100644 --- a/src/util.ts +++ b/src/util.ts @@ -3,7 +3,7 @@ import * as minimatch from 'minimatch'; import { BsLintConfig, BsLintRules, RuleSeverity, BsLintSeverity } from './index'; import { readFileSync, existsSync } from 'fs'; import * as path from 'path'; -import { Program, File, DiagnosticSeverity } from 'brighterscript'; +import { Program, BscFile, DiagnosticSeverity } from 'brighterscript'; import { applyFixes, ChangeEntry, TextEdit } from './textEdit'; import { addJob } from './Linter'; @@ -99,10 +99,10 @@ export interface PluginContext { severity: Readonly; todoPattern: Readonly; globals: string[]; - ignores: (file: File) => boolean; + ignores: (file: BscFile) => boolean; fix: Readonly; checkUsage: Readonly; - addFixes: (file: File, entry: ChangeEntry) => void; + addFixes: (file: BscFile, entry: ChangeEntry) => void; } export interface PluginWrapperContext extends PluginContext { @@ -121,12 +121,12 @@ export function createContext(program: Program): PluginWrapperContext { severity: rulesToSeverity(rules), todoPattern: rules['todo-pattern'] ? new RegExp(rules['todo-pattern']) : /TODO|todo|FIXME/, globals, - ignores: (file: File) => { + ignores: (file: BscFile) => { return !file || ignorePatterns.some(pattern => minimatch(file.srcPath, pattern)); }, fix, checkUsage, - addFixes: (file: File, entry: ChangeEntry) => { + addFixes: (file: BscFile, entry: ChangeEntry) => { if (!pendingFixes.has(file.srcPath)) { pendingFixes.set(file.srcPath, entry.changes); } else {