17 Star 68 Fork 20

Microsoft/vscode

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
eslint.config.js 45.61 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// @ts-check
import fs from 'fs';
import path from 'path';
import tseslint from 'typescript-eslint';
import { fileURLToPath } from 'url';
import stylisticTs from '@stylistic/eslint-plugin-ts';
import pluginLocal from 'eslint-plugin-local';
import pluginJsdoc from 'eslint-plugin-jsdoc';
import pluginHeader from 'eslint-plugin-header';
pluginHeader.rules.header.meta.schema = false;
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ignores = fs.readFileSync(path.join(__dirname, '.eslint-ignore'), 'utf8')
.toString()
.split(/\r\n|\n/)
.filter(line => line && !line.startsWith('#'));
export default tseslint.config(
// Global ignores
{
ignores,
},
// All files (JS and TS)
{
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
'header': pluginHeader,
},
rules: {
'constructor-super': 'warn',
'curly': 'warn',
'eqeqeq': 'warn',
'prefer-const': [
'warn',
{
'destructuring': 'all'
}
],
'no-buffer-constructor': 'warn',
'no-caller': 'warn',
'no-case-declarations': 'warn',
'no-debugger': 'warn',
'no-duplicate-case': 'warn',
'no-duplicate-imports': 'warn',
'no-eval': 'warn',
'no-async-promise-executor': 'warn',
'no-extra-semi': 'warn',
'no-new-wrappers': 'warn',
'no-redeclare': 'off',
'no-sparse-arrays': 'warn',
'no-throw-literal': 'warn',
'no-unsafe-finally': 'warn',
'no-unused-labels': 'warn',
'no-misleading-character-class': 'warn',
'no-restricted-globals': [
'warn',
'name',
'length',
'event',
'closed',
'external',
'status',
'origin',
'orientation',
'context'
], // non-complete list of globals that are easy to access unintentionally
'no-var': 'warn',
'semi': 'off',
'local/code-translation-remind': 'warn',
'local/code-no-native-private': 'warn',
'local/code-parameter-properties-must-have-explicit-accessibility': 'warn',
'local/code-no-nls-in-standalone-editor': 'warn',
'local/code-no-potentially-unsafe-disposables': 'warn',
'local/code-no-dangerous-type-assertions': 'warn',
'local/code-no-standalone-editor': 'warn',
'local/code-no-unexternalized-strings': 'warn',
'local/code-must-use-super-dispose': 'warn',
'local/code-declare-service-brand': 'warn',
'local/code-layering': [
'warn',
{
'common': [],
'node': [
'common'
],
'browser': [
'common'
],
'electron-sandbox': [
'common',
'browser'
],
'electron-utility': [
'common',
'node'
],
'electron-main': [
'common',
'node',
'electron-utility'
]
}
],
'header/header': [
2,
'block',
[
'---------------------------------------------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
' * Licensed under the MIT License. See License.txt in the project root for license information.',
' *--------------------------------------------------------------------------------------------'
]
]
},
},
// TS
{
files: [
'**/*.ts',
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'@stylistic/ts': stylisticTs,
'@typescript-eslint': tseslint.plugin,
'local': pluginLocal,
'jsdoc': pluginJsdoc,
},
rules: {
'@stylistic/ts/semi': 'warn',
'@stylistic/ts/member-delimiter-style': 'warn',
'local/code-no-unused-expressions': [
'warn',
{
'allowTernary': true
}
],
'jsdoc/no-types': 'warn',
'local/code-no-static-self-ref': 'warn'
}
},
// vscode TS
{
files: [
'src/**/*.ts',
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'@typescript-eslint': tseslint.plugin,
},
rules: {
'@typescript-eslint/naming-convention': [
'warn',
{
'selector': 'class',
'format': [
'PascalCase'
]
}
]
}
},
// Tests
{
files: [
'**/*.test.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'local/code-must-use-super-dispose': 'off',
'local/code-no-test-only': 'error',
'local/code-no-test-async-suite': 'warn',
'local/code-no-unexternalized-strings': 'off',
'local/code-must-use-result': [
'warn',
[
{
'message': 'Expression must be awaited',
'functions': [
'assertSnapshot',
'assertHeap'
]
}
]
]
}
},
// vscode tests specific rules
{
files: [
'src/vs/**/*.test.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'local/code-ensure-no-disposables-leak-in-test': [
'warn',
{
// Files should (only) be removed from the list they adopt the leak detector
'exclude': [
'src/vs/editor/contrib/codeAction/test/browser/codeActionModel.test.ts',
'src/vs/platform/configuration/test/common/configuration.test.ts',
'src/vs/platform/opener/test/common/opener.test.ts',
'src/vs/platform/registry/test/common/platform.test.ts',
'src/vs/platform/workspace/test/common/workspace.test.ts',
'src/vs/platform/workspaces/test/electron-main/workspaces.test.ts',
'src/vs/workbench/api/test/browser/mainThreadConfiguration.test.ts',
'src/vs/workbench/api/test/node/extHostTunnelService.test.ts',
'src/vs/workbench/contrib/bulkEdit/test/browser/bulkCellEdits.test.ts',
'src/vs/workbench/contrib/chat/test/common/chatWordCounter.test.ts',
'src/vs/workbench/contrib/extensions/test/common/extensionQuery.test.ts',
'src/vs/workbench/contrib/notebook/test/browser/notebookExecutionService.test.ts',
'src/vs/workbench/contrib/notebook/test/browser/notebookExecutionStateService.test.ts',
'src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts',
'src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts',
'src/vs/workbench/services/commands/test/common/commandService.test.ts',
'src/vs/workbench/services/userActivity/test/browser/domActivityTracker.test.ts',
'src/vs/workbench/test/browser/quickAccess.test.ts'
]
}
]
}
},
// vscode API
{
files: [
'**/vscode.d.ts',
'**/vscode.proposed.*.d.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'no-restricted-syntax': [
'warn',
{
'selector': `TSArrayType > TSUnionType`,
'message': 'Use Array<...> for arrays of union types.'
},
],
'local/vscode-dts-create-func': 'warn',
'local/vscode-dts-literal-or-types': 'warn',
'local/vscode-dts-string-type-literals': 'warn',
'local/vscode-dts-interface-naming': 'warn',
'local/vscode-dts-cancellation': 'warn',
'local/vscode-dts-use-thenable': 'warn',
'local/vscode-dts-region-comments': 'warn',
'local/vscode-dts-vscode-in-comments': 'warn',
'local/vscode-dts-provider-naming': [
'warn',
{
'allowed': [
'FileSystemProvider',
'TreeDataProvider',
'TestProvider',
'CustomEditorProvider',
'CustomReadonlyEditorProvider',
'TerminalLinkProvider',
'AuthenticationProvider',
'NotebookContentProvider'
]
}
],
'local/vscode-dts-event-naming': [
'warn',
{
'allowed': [
'onCancellationRequested',
'event'
],
'verbs': [
'accept',
'change',
'close',
'collapse',
'create',
'delete',
'discover',
'dispose',
'drop',
'edit',
'end',
'execute',
'expand',
'grant',
'hide',
'invalidate',
'open',
'override',
'perform',
'receive',
'register',
'remove',
'rename',
'save',
'send',
'start',
'terminate',
'trigger',
'unregister',
'write'
]
}
]
}
},
// vscode.d.ts
{
files: [
'**/vscode.d.ts'
],
languageOptions: {
parser: tseslint.parser,
},
rules: {
'jsdoc/tag-lines': 'off',
'jsdoc/valid-types': 'off',
'jsdoc/no-multi-asterisks': [
'warn',
{
'allowWhitespace': true
}
],
'jsdoc/require-jsdoc': [
'warn',
{
'enableFixer': false,
'contexts': [
'TSInterfaceDeclaration',
'TSPropertySignature',
'TSMethodSignature',
'TSDeclareFunction',
'ClassDeclaration',
'MethodDefinition',
'PropertyDeclaration',
'TSEnumDeclaration',
'TSEnumMember',
'ExportNamedDeclaration'
]
}
],
'jsdoc/check-param-names': [
'warn',
{
'enableFixer': false,
'checkDestructured': false
}
],
'jsdoc/require-returns': 'warn'
}
},
// common/browser layer
{
files: [
'src/**/{common,browser}/**/*.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'local/code-amd-node-module': 'warn'
}
},
// node/electron layer
{
files: [
'src/*.ts',
'src/**/{node,electron-main,electron-utility}/**/*.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'no-restricted-globals': [
'warn',
'name',
'length',
'event',
'closed',
'external',
'status',
'origin',
'orientation',
'context',
// Below are globals that are unsupported in ESM
'__dirname',
'__filename',
'require'
]
}
},
// browser/electron-sandbox layer
{
files: [
'src/**/{browser,electron-sandbox}/**/*.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'local/code-no-global-document-listener': 'warn',
'no-restricted-syntax': [
'warn',
{
'selector': `BinaryExpression[operator='instanceof'][right.name='MouseEvent']`,
'message': 'Use DOM.isMouseEvent() to support multi-window scenarios.'
},
{
'selector': `BinaryExpression[operator='instanceof'][right.name=/^HTML\\w+/]`,
'message': 'Use DOM.isHTMLElement() and related methods to support multi-window scenarios.'
},
{
'selector': `BinaryExpression[operator='instanceof'][right.name=/^SVG\\w+/]`,
'message': 'Use DOM.isSVGElement() and related methods to support multi-window scenarios.'
},
{
'selector': `BinaryExpression[operator='instanceof'][right.name='KeyboardEvent']`,
'message': 'Use DOM.isKeyboardEvent() to support multi-window scenarios.'
},
{
'selector': `BinaryExpression[operator='instanceof'][right.name='PointerEvent']`,
'message': 'Use DOM.isPointerEvent() to support multi-window scenarios.'
},
{
'selector': `BinaryExpression[operator='instanceof'][right.name='DragEvent']`,
'message': 'Use DOM.isDragEvent() to support multi-window scenarios.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='activeElement']`,
'message': 'Use <targetWindow>.document.activeElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='contains']`,
'message': 'Use <targetWindow>.document.contains to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='styleSheets']`,
'message': 'Use <targetWindow>.document.styleSheets to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='fullscreenElement']`,
'message': 'Use <targetWindow>.document.fullscreenElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='body']`,
'message': 'Use <targetWindow>.document.body to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='addEventListener']`,
'message': 'Use <targetWindow>.document.addEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='removeEventListener']`,
'message': 'Use <targetWindow>.document.removeEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='hasFocus']`,
'message': 'Use <targetWindow>.document.hasFocus to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='head']`,
'message': 'Use <targetWindow>.document.head to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='exitFullscreen']`,
'message': 'Use <targetWindow>.document.exitFullscreen to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='getElementById']`,
'message': 'Use <targetWindow>.document.getElementById to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='getElementsByClassName']`,
'message': 'Use <targetWindow>.document.getElementsByClassName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='getElementsByName']`,
'message': 'Use <targetWindow>.document.getElementsByName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='getElementsByTagName']`,
'message': 'Use <targetWindow>.document.getElementsByTagName to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='getElementsByTagNameNS']`,
'message': 'Use <targetWindow>.document.getElementsByTagNameNS to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='getSelection']`,
'message': 'Use <targetWindow>.document.getSelection to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='open']`,
'message': 'Use <targetWindow>.document.open to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='close']`,
'message': 'Use <targetWindow>.document.close to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='documentElement']`,
'message': 'Use <targetWindow>.document.documentElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='visibilityState']`,
'message': 'Use <targetWindow>.document.visibilityState to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='querySelector']`,
'message': 'Use <targetWindow>.document.querySelector to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='querySelectorAll']`,
'message': 'Use <targetWindow>.document.querySelectorAll to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='elementFromPoint']`,
'message': 'Use <targetWindow>.document.elementFromPoint to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='elementsFromPoint']`,
'message': 'Use <targetWindow>.document.elementsFromPoint to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='onkeydown']`,
'message': 'Use <targetWindow>.document.onkeydown to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='onkeyup']`,
'message': 'Use <targetWindow>.document.onkeyup to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='onmousedown']`,
'message': 'Use <targetWindow>.document.onmousedown to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='onmouseup']`,
'message': 'Use <targetWindow>.document.onmouseup to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'selector': `MemberExpression[object.name='document'][property.name='execCommand']`,
'message': 'Use <targetWindow>.document.execCommand to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
}
],
'no-restricted-globals': [
'warn',
'name',
'length',
'event',
'closed',
'external',
'status',
'origin',
'orientation',
'context',
{
'name': 'setInterval',
'message': 'Use <targetWindow>.setInterval to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'clearInterval',
'message': 'Use <targetWindow>.clearInterval to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'requestAnimationFrame',
'message': 'Use <targetWindow>.requestAnimationFrame to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'cancelAnimationFrame',
'message': 'Use <targetWindow>.cancelAnimationFrame to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'requestIdleCallback',
'message': 'Use <targetWindow>.requestIdleCallback to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'cancelIdleCallback',
'message': 'Use <targetWindow>.cancelIdleCallback to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'window',
'message': 'Use <targetWindow> to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'addEventListener',
'message': 'Use <targetWindow>.addEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'removeEventListener',
'message': 'Use <targetWindow>.removeEventListener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'getComputedStyle',
'message': 'Use <targetWindow>.getComputedStyle to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'focus',
'message': 'Use <targetWindow>.focus to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'blur',
'message': 'Use <targetWindow>.blur to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'close',
'message': 'Use <targetWindow>.close to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'dispatchEvent',
'message': 'Use <targetWindow>.dispatchEvent to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'getSelection',
'message': 'Use <targetWindow>.getSelection to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'matchMedia',
'message': 'Use <targetWindow>.matchMedia to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'open',
'message': 'Use <targetWindow>.open to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'parent',
'message': 'Use <targetWindow>.parent to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'postMessage',
'message': 'Use <targetWindow>.postMessage to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'devicePixelRatio',
'message': 'Use <targetWindow>.devicePixelRatio to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'frames',
'message': 'Use <targetWindow>.frames to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'frameElement',
'message': 'Use <targetWindow>.frameElement to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'innerHeight',
'message': 'Use <targetWindow>.innerHeight to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'innerWidth',
'message': 'Use <targetWindow>.innerWidth to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'outerHeight',
'message': 'Use <targetWindow>.outerHeight to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'outerWidth',
'message': 'Use <targetWindow>.outerWidth to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'opener',
'message': 'Use <targetWindow>.opener to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'origin',
'message': 'Use <targetWindow>.origin to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'screen',
'message': 'Use <targetWindow>.screen to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'screenLeft',
'message': 'Use <targetWindow>.screenLeft to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'screenTop',
'message': 'Use <targetWindow>.screenTop to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'screenX',
'message': 'Use <targetWindow>.screenX to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'screenY',
'message': 'Use <targetWindow>.screenY to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'scrollX',
'message': 'Use <targetWindow>.scrollX to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'scrollY',
'message': 'Use <targetWindow>.scrollY to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'top',
'message': 'Use <targetWindow>.top to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
},
{
'name': 'visualViewport',
'message': 'Use <targetWindow>.visualViewport to support multi-window scenarios. Resolve targetWindow with DOM.getWindow(element) or DOM.getActiveWindow() or use the predefined mainWindow constant.'
}
]
}
},
// electron-utility layer
{
files: [
'src/**/electron-utility/**/*.ts'
],
languageOptions: {
parser: tseslint.parser,
},
rules: {
'no-restricted-imports': [
'warn',
{
'paths': [
{
'name': 'electron',
'allowImportNames': [
'net',
'system-preferences',
],
'message': 'Only net and system-preferences are allowed to be imported from electron'
}
]
}
]
}
},
{
files: [
'src/**/*.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'local/code-import-patterns': [
'warn',
{
// imports that are allowed in all files of layers:
// - browser
// - electron-sandbox
'when': 'hasBrowser',
'allow': []
},
{
// imports that are allowed in all files of layers:
// - node
// - electron-utility
// - electron-main
'when': 'hasNode',
'allow': [
'@parcel/watcher',
'@vscode/sqlite3',
'@vscode/vscode-languagedetection',
'@vscode/ripgrep',
'@vscode/iconv-lite-umd',
'@vscode/policy-watcher',
'@vscode/proxy-agent',
'@vscode/spdlog',
'@vscode/windows-process-tree',
'assert',
'child_process',
'console',
'cookie',
'crypto',
'dns',
'events',
'fs',
'fs/promises',
'http',
'https',
'minimist',
'node:module',
'native-keymap',
'native-watchdog',
'net',
'node-pty',
'os',
'path',
'perf_hooks',
'readline',
'stream',
'string_decoder',
'tas-client-umd',
'tls',
'undici-types',
'url',
'util',
'v8-inspect-profiler',
'vscode-regexpp',
'vscode-textmate',
'worker_threads',
'@xterm/addon-clipboard',
'@xterm/addon-image',
'@xterm/addon-ligatures',
'@xterm/addon-search',
'@xterm/addon-serialize',
'@xterm/addon-unicode11',
'@xterm/addon-webgl',
'@xterm/headless',
'@xterm/xterm',
'yauzl',
'yazl',
'zlib'
]
},
{
// imports that are allowed in all files of layers:
// - electron-utility
// - electron-main
'when': 'hasElectron',
'allow': [
'electron'
]
},
{
// imports that are allowed in all /test/ files
'when': 'test',
'allow': [
'assert',
'sinon',
'sinon-test'
]
},
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!! Do not relax these rules !!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// A path ending in /~ has a special meaning. It indicates a template position
// which will be substituted with one or more layers.
//
// When /~ is used in the target, the rule will be expanded to 14 distinct rules.
// e.g. 'src/vs/base/~' will be expanded to:
// - src/vs/base/common
// - src/vs/base/worker
// - src/vs/base/browser
// - src/vs/base/electron-sandbox
// - src/vs/base/node
// - src/vs/base/electron-main
// - src/vs/base/test/common
// - src/vs/base/test/worker
// - src/vs/base/test/browser
// - src/vs/base/test/electron-sandbox
// - src/vs/base/test/node
// - src/vs/base/test/electron-main
//
// When /~ is used in the restrictions, it will be replaced with the correct
// layers that can be used e.g. 'src/vs/base/electron-sandbox' will be able
// to import '{common,browser,electron-sanbox}', etc.
//
// It is possible to use /~ in the restrictions property even without using it in
// the target property by adding a layer property.
{
'target': 'src/vs/base/~',
'restrictions': [
'vs/base/~'
]
},
{
'target': 'src/vs/base/parts/*/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~'
]
},
{
'target': 'src/vs/platform/*/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'tas-client-umd', // node module allowed even in /common/
'@microsoft/1ds-core-js', // node module allowed even in /common/
'@microsoft/1ds-post-js', // node module allowed even in /common/
'@xterm/headless' // node module allowed even in /common/
]
},
{
'target': 'src/vs/editor/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'@vscode/tree-sitter-wasm' // node module allowed even in /common/
]
},
{
'target': 'src/vs/editor/contrib/*/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~'
]
},
{
'target': 'src/vs/editor/standalone/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/editor/standalone/~',
'@vscode/tree-sitter-wasm' // type import
]
},
{
'target': 'src/vs/editor/editor.all.ts',
'layer': 'browser',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~'
]
},
{
'target': 'src/vs/editor/editor.worker.ts',
'layer': 'worker',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~'
]
},
{
'target': 'src/vs/editor/{editor.api.ts,editor.main.ts}',
'layer': 'browser',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/editor/standalone/~',
'vs/editor/*'
]
},
{
'target': 'src/vs/workbench/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/workbench/~',
'vs/workbench/services/*/~',
'assert',
{
'when': 'test',
'pattern': 'vs/workbench/contrib/*/~'
} // TODO@layers
]
},
{
'target': 'src/vs/workbench/api/~',
'restrictions': [
'vscode',
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/workbench/api/~',
'vs/workbench/~',
'vs/workbench/services/*/~',
'vs/workbench/contrib/*/~',
'vs/workbench/contrib/terminalContrib/*/~'
]
},
{
'target': 'src/vs/workbench/services/*/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/workbench/~',
'vs/workbench/services/*/~',
{
'when': 'test',
'pattern': 'vs/workbench/contrib/*/~'
}, // TODO@layers
'tas-client-umd', // node module allowed even in /common/
'vscode-textmate', // node module allowed even in /common/
'@vscode/vscode-languagedetection', // node module allowed even in /common/
'@vscode/tree-sitter-wasm', // type import
{
'when': 'hasBrowser',
'pattern': '@xterm/xterm'
} // node module allowed even in /browser/
]
},
{
'target': 'src/vs/workbench/contrib/*/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/workbench/~',
'vs/workbench/services/*/~',
'vs/workbench/contrib/*/~',
'vs/workbench/contrib/terminal/terminalContribChatExports*',
'vs/workbench/contrib/terminal/terminalContribExports*',
'vscode-notebook-renderer', // Type only import
'@vscode/tree-sitter-wasm', // type import
{
'when': 'hasBrowser',
'pattern': '@xterm/xterm'
}, // node module allowed even in /browser/
{
'when': 'hasBrowser',
'pattern': '@xterm/addon-*'
}, // node module allowed even in /browser/
{
'when': 'hasBrowser',
'pattern': 'vscode-textmate'
} // node module allowed even in /browser/
]
},
{
'target': 'src/vs/workbench/contrib/terminalContrib/*/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/workbench/~',
'vs/workbench/services/*/~',
'vs/workbench/contrib/*/~',
// Only allow terminalContrib to import from itself, this works because
// terminalContrib is one extra folder deep
'vs/workbench/contrib/terminalContrib/*/~',
'vscode-notebook-renderer', // Type only import
{
'when': 'hasBrowser',
'pattern': '@xterm/xterm'
}, // node module allowed even in /browser/
{
'when': 'hasBrowser',
'pattern': '@xterm/addon-*'
}, // node module allowed even in /browser/
{
'when': 'hasBrowser',
'pattern': 'vscode-textmate'
}, // node module allowed even in /browser/
'@xterm/headless' // node module allowed even in /common/ and /browser/
]
},
{
'target': 'src/vs/code/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/code/~',
{
'when': 'hasBrowser',
'pattern': 'vs/workbench/workbench.web.main.js'
},
{
'when': 'hasBrowser',
'pattern': 'vs/workbench/workbench.web.main.internal.js'
},
{
'when': 'hasBrowser',
'pattern': 'vs/workbench/~'
},
{
'when': 'hasBrowser',
'pattern': 'vs/workbench/services/*/~'
}
]
},
{
'target': 'src/vs/server/~',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/workbench/~',
'vs/workbench/api/~',
'vs/workbench/services/*/~',
'vs/workbench/contrib/*/~',
'vs/server/~'
]
},
{
'target': 'src/vs/workbench/contrib/terminal/terminal.all.ts',
'layer': 'browser',
'restrictions': [
'vs/workbench/contrib/**'
]
},
{
'target': 'src/vs/workbench/contrib/terminal/terminalContribChatExports.ts',
'layer': 'browser',
'restrictions': [
'vs/workbench/contrib/terminalContrib/*/~'
]
},
{
'target': 'src/vs/workbench/contrib/terminal/terminalContribExports.ts',
'layer': 'browser',
'restrictions': [
'vs/platform/*/~',
'vs/workbench/contrib/terminalContrib/*/~'
]
},
{
'target': 'src/vs/workbench/workbench.common.main.ts',
'layer': 'browser',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/editor/editor.all.js',
'vs/workbench/~',
'vs/workbench/api/~',
'vs/workbench/services/*/~',
'vs/workbench/contrib/*/~',
'vs/workbench/contrib/terminal/terminal.all.js'
]
},
{
'target': 'src/vs/workbench/workbench.web.main.ts',
'layer': 'browser',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/editor/editor.all.js',
'vs/workbench/~',
'vs/workbench/api/~',
'vs/workbench/services/*/~',
'vs/workbench/contrib/*/~',
'vs/workbench/workbench.common.main.js'
]
},
{
'target': 'src/vs/workbench/workbench.web.main.internal.ts',
'layer': 'browser',
'restrictions': [
'vs/base/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/editor/editor.all.js',
'vs/workbench/~',
'vs/workbench/api/~',
'vs/workbench/services/*/~',
'vs/workbench/contrib/*/~',
'vs/workbench/workbench.common.main.js'
]
},
{
'target': 'src/vs/workbench/workbench.desktop.main.ts',
'layer': 'electron-sandbox',
'restrictions': [
'vs/base/*/~',
'vs/base/parts/*/~',
'vs/platform/*/~',
'vs/editor/~',
'vs/editor/contrib/*/~',
'vs/editor/editor.all.js',
'vs/workbench/~',
'vs/workbench/api/~',
'vs/workbench/services/*/~',
'vs/workbench/contrib/*/~',
'vs/workbench/workbench.common.main.js'
]
},
{
'target': 'src/vs/amdX.ts',
'restrictions': [
'vs/base/common/*'
]
},
{
'target': 'src/vs/{loader.d.ts,monaco.d.ts,nls.ts,nls.messages.ts}',
'restrictions': []
},
{
'target': 'src/vscode-dts/**',
'restrictions': []
},
{
'target': 'src/bootstrap-window.ts',
'restrictions': []
},
{
'target': 'src/vs/nls.ts',
'restrictions': [
'vs/*'
]
},
{
'target': 'src/{bootstrap-cli.ts,bootstrap-esm.ts,bootstrap-fork.ts,bootstrap-import.ts,bootstrap-meta.ts,bootstrap-node.ts,bootstrap-server.ts,cli.ts,main.ts,server-cli.ts,server-main.ts}',
'restrictions': [
'vs/**/common/*',
'vs/**/node/*',
'vs/nls.js',
'src/*.js',
'*' // node.js
]
}
]
}
},
{
files: [
'test/**/*.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'local/code-import-patterns': [
'warn',
{
'target': 'test/smoke/**',
'restrictions': [
'test/automation',
'test/smoke/**',
'@vscode/*',
'@parcel/*',
'@playwright/*',
'*' // node modules
]
},
{
'target': 'test/automation/**',
'restrictions': [
'test/automation/**',
'@vscode/*',
'@parcel/*',
'playwright-core/**',
'@playwright/*',
'*' // node modules
]
},
{
'target': 'test/integration/**',
'restrictions': [
'test/integration/**',
'@vscode/*',
'@parcel/*',
'@playwright/*',
'*' // node modules
]
},
{
'target': 'test/monaco/**',
'restrictions': [
'test/monaco/**',
'@vscode/*',
'@parcel/*',
'@playwright/*',
'*' // node modules
]
}
]
}
},
{
files: [
'src/vs/workbench/contrib/notebook/browser/view/renderers/*.ts'
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'local': pluginLocal,
},
rules: {
'local/code-no-runtime-import': [
'error',
{
'src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts': [
'**/*'
]
}
],
'local/code-limited-top-functions': [
'error',
{
'src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts': [
'webviewPreloads',
'preloadsScriptStr'
]
}
]
}
},
// Terminal
{
files: [
'src/vs/workbench/contrib/terminal/**/*.ts',
'src/vs/workbench/contrib/terminalContrib/**/*.ts',
],
languageOptions: {
parser: tseslint.parser,
},
rules: {
'@typescript-eslint/naming-convention': [
'warn',
// variableLike
{ 'selector': 'variable', 'format': ['camelCase', 'UPPER_CASE', 'PascalCase'] },
{ 'selector': 'variable', 'filter': '^I.+Service$', 'format': ['PascalCase'], 'prefix': ['I'] },
// memberLike
{ 'selector': 'memberLike', 'modifiers': ['private'], 'format': ['camelCase'], 'leadingUnderscore': 'require' },
{ 'selector': 'memberLike', 'modifiers': ['protected'], 'format': ['camelCase'], 'leadingUnderscore': 'require' },
{ 'selector': 'enumMember', 'format': ['PascalCase'] },
// memberLike - Allow enum-like objects to use UPPER_CASE
{ 'selector': 'method', 'modifiers': ['public'], 'format': ['camelCase', 'UPPER_CASE'] },
// typeLike
{ 'selector': 'typeLike', 'format': ['PascalCase'] },
{ 'selector': 'interface', 'format': ['PascalCase'] }
],
'comma-dangle': ['warn', 'only-multiline']
}
},
// markdown-language-features
{
files: [
'extensions/markdown-language-features/**/*.ts',
],
languageOptions: {
parser: tseslint.parser,
},
plugins: {
'@typescript-eslint': tseslint.plugin,
},
rules: {
'@typescript-eslint/naming-convention': [
'warn',
{
'selector': 'default',
'modifiers': ['private'],
'format': null,
'leadingUnderscore': 'require'
},
{
'selector': 'default',
'modifiers': ['public'],
'format': null,
'leadingUnderscore': 'forbid'
}
]
}
},
// typescript-language-features
{
files: [
'extensions/typescript-language-features/**/*.ts',
],
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: [
'extensions/typescript-language-features/tsconfig.json',
'extensions/typescript-language-features/web/tsconfig.json'
],
}
},
plugins: {
'@typescript-eslint': tseslint.plugin,
},
rules: {
'@typescript-eslint/prefer-optional-chain': 'warn',
'@typescript-eslint/prefer-readonly': 'warn',
}
}
);
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/microsoft/vscode.git
[email protected]:microsoft/vscode.git
microsoft
vscode
vscode
main

搜索帮助