debt - more powerful layer checker with TS support (#250752)

This commit is contained in:
Benjamin Pasero 2025-06-06 08:56:50 +02:00 committed by GitHub
parent 7774f735cd
commit 5535b4579f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 94 additions and 11 deletions

View File

@ -279,7 +279,7 @@ function checkFile(program, sourceFile, rule) {
}
if (rule.disallowedTypes?.some(disallowed => disallowed === text)) {
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
console.log(`[build/lib/layersChecker.ts]: Reference to type '${text}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}). Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`);
console.log(`[build/checker/layersChecker.ts]: Reference to type '${text}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}). Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`);
hasErrors = true;
return;
}
@ -303,7 +303,7 @@ function checkFile(program, sourceFile, rule) {
for (const disallowedDefinition of rule.disallowedDefinitions) {
if (definitionFileName.indexOf(disallowedDefinition) >= 0) {
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
console.log(`[build/lib/layersChecker.ts]: Reference to symbol '${text}' from '${disallowedDefinition}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}) Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`);
console.log(`[build/checker/layersChecker.ts]: Reference to symbol '${text}' from '${disallowedDefinition}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}) Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`);
hasErrors = true;
return;
}

View File

@ -318,7 +318,7 @@ function checkFile(program: ts.Program, sourceFile: ts.SourceFile, rule: IRule)
if (rule.disallowedTypes?.some(disallowed => disallowed === text)) {
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
console.log(`[build/lib/layersChecker.ts]: Reference to type '${text}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}). Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`);
console.log(`[build/checker/layersChecker.ts]: Reference to type '${text}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}). Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`);
hasErrors = true;
return;
@ -345,7 +345,7 @@ function checkFile(program: ts.Program, sourceFile: ts.SourceFile, rule: IRule)
if (definitionFileName.indexOf(disallowedDefinition) >= 0) {
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
console.log(`[build/lib/layersChecker.ts]: Reference to symbol '${text}' from '${disallowedDefinition}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}) Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`);
console.log(`[build/checker/layersChecker.ts]: Reference to symbol '${text}' from '${disallowedDefinition}' violates layer '${rule.target}' (${sourceFile.fileName} (${line + 1},${character + 1}) Learn more about our source code organization at https://github.com/microsoft/vscode/wiki/Source-Code-Organization.`);
hasErrors = true;
return;

View File

@ -0,0 +1,21 @@
{
"extends": "./tsconfig.web.json",
"include": [
"../../src/**/common/**/*.ts",
"../../src/**/browser/**/*.ts",
"../../src/**/electron-sandbox/**/*.ts",
"../../src/typings/*.d.ts",
"../../src/vs/monaco.d.ts",
"../../src/vscode-dts/vscode.proposed.*.d.ts",
"../../src/vscode-dts/vscode.d.ts",
"../../node_modules/@webgpu/types/dist/index.d.ts",
"../../node_modules/@types/trusted-types/index.d.ts",
"../../node_modules/@types/wicg-file-system-access/index.d.ts"
],
"exclude": [
"../../src/**/test/**",
"../../src/**/fixtures/**",
"../../src/vs/base/parts/sandbox/electron-sandbox/preload.ts", // Preload scripts for Electron sandbox
"../../src/vs/base/parts/sandbox/electron-sandbox/preload-aux.ts" // have limited access to node.js APIs
]
}

View File

@ -0,0 +1,26 @@
{
"extends": "../../src/tsconfig.base.json",
"compilerOptions": {
"lib": [
"ES2022"
],
"types": [
"node"
],
"noEmit": true,
"skipLibCheck": true
},
"include": [
"../../src/**/common/**/*.ts",
"../../src/**/node/**/*.ts",
"../../src/typings/*.d.ts",
"../../src/vs/monaco.d.ts",
"../../src/vscode-dts/vscode.proposed.*.d.ts",
"../../src/vscode-dts/vscode.d.ts",
"../../node_modules/@types/trusted-types/index.d.ts",
],
"exclude": [
"../../src/**/test/**",
"../../src/**/fixtures/**"
]
}

View File

@ -0,0 +1,28 @@
{
"extends": "../../src/tsconfig.base.json",
"compilerOptions": {
"lib": [
"ES2022",
"DOM",
"DOM.Iterable"
],
"types": [],
"noEmit": true,
"skipLibCheck": true
},
"include": [
"../../src/**/common/**/*.ts",
"../../src/**/browser/**/*.ts",
"../../src/typings/*.d.ts",
"../../src/vs/monaco.d.ts",
"../../src/vscode-dts/vscode.proposed.*.d.ts",
"../../src/vscode-dts/vscode.d.ts",
"../../node_modules/@webgpu/types/dist/index.d.ts",
"../../node_modules/@types/trusted-types/index.d.ts",
"../../node_modules/@types/wicg-file-system-access/index.d.ts"
],
"exclude": [
"../../src/**/test/**",
"../../src/**/fixtures/**"
]
}

View File

@ -103,6 +103,7 @@ module.exports.indentationFilter = [
'!extensions/vscode-api-tests/testWorkspace2/**',
'!build/monaco/**',
'!build/win32/**',
'!build/checker/**',
// except multiple specific files
'!**/package.json',

View File

@ -44,7 +44,7 @@
"monaco-compile-check": "tsc -p src/tsconfig.monaco.json --noEmit",
"tsec-compile-check": "node node_modules/tsec/bin/tsec -p src/tsconfig.tsec.json",
"vscode-dts-compile-check": "tsc -p src/tsconfig.vscode-dts.json && tsc -p src/tsconfig.vscode-proposed-dts.json",
"valid-layers-check": "node build/lib/layersChecker.js",
"valid-layers-check": "node build/checker/layersChecker.js && tsc -p build/checker/tsconfig.web.json && tsc -p build/checker/tsconfig.desktop.json && tsc -p build/checker/tsconfig.server.json",
"define-class-fields-check": "node build/lib/propertyInitOrderChecker.js && tsc -p src/tsconfig.defineClassFields.json",
"update-distro": "node build/npm/update-distro.mjs",
"web": "echo 'npm run web' is replaced by './scripts/code-server' or './scripts/code-web'",

View File

@ -17,6 +17,7 @@ declare global {
function requestIdleCallback(callback: (args: IdleDeadline) => void, options?: { timeout: number }): number;
function cancelIdleCallback(handle: number): void;
// --- timeout / interval (available in all contexts, but different signatures in node.js vs web)
interface TimeoutHandle {readonly _: never; /* this is a trick that seems needed to prevent direct number assignment */}
@ -26,6 +27,14 @@ declare global {
function setInterval(callback: (...args: any[]) => void, delay?: number, ...args: any[]): Timeout;
function clearInterval(timeout: Timeout | undefined): void;
// --- error
interface ErrorConstructor {
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
stackTraceLimit: number;
}
}
export { }

View File

@ -36,7 +36,6 @@ export namespace WebFileSystemAccess {
}
}
// TODO@bpasero adopt official types of FileSystemObserver
export namespace WebFileSystemObserver {
export function supported(obj: any & Window): boolean {

View File

@ -593,8 +593,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
try {
activationTimesBuilder.activateCallStart();
logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`);
const scope = typeof global === 'object' ? global : self; // `global` is nodejs while `self` is for workers
const activateResult: Promise<IExtensionAPI> = extensionModule.activate.apply(scope, [context]);
const activateResult: Promise<IExtensionAPI> = extensionModule.activate.apply(globalThis, [context]);
activationTimesBuilder.activateCallStop();
activationTimesBuilder.activateResolveStart();

View File

@ -17,7 +17,7 @@ import { Promises } from '../../../base/node/pfs.js';
import { IMessagePassingProtocol } from '../../../base/parts/ipc/common/ipc.js';
import { BufferedEmitter, PersistentProtocol, ProtocolConstants } from '../../../base/parts/ipc/common/ipc.net.js';
import { NodeSocket, WebSocketNodeSocket } from '../../../base/parts/ipc/node/ipc.net.js';
import type { MessagePortMain } from '../../../base/parts/sandbox/node/electronTypes.js';
import type { MessagePortMain, MessageEvent as UtilityMessageEvent } from '../../../base/parts/sandbox/node/electronTypes.js';
import { boolean } from '../../../editor/common/config/editorOptions.js';
import product from '../../../platform/product/common/product.js';
import { ExtensionHostMain, IExitFn } from '../common/extensionHostMain.js';
@ -92,7 +92,7 @@ function patchProcess(allowExit: boolean) {
} as (code?: number) => never;
// override Electron's process.crash() method
process.crash = function () {
(process as any /* bypass layer checker */).crash = function () {
const err = new Error('An extension called process.crash() and this was prevented.');
console.warn(err.stack);
};
@ -167,7 +167,7 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
});
};
process.parentPort.on('message', (e: Electron.MessageEvent) => withPorts(e.ports));
(process as unknown as { parentPort: { on: (event: 'message', listener: (messageEvent: UtilityMessageEvent) => void) => void } }).parentPort.on('message', (e: UtilityMessageEvent) => withPorts(e.ports));
});
} else if (extHostConnection.type === ExtHostConnectionType.Socket) {