Path: blob/main/extensions/copilot/test/simulation/diagnosticProviders/eslint.ts
13394 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import * as fs from 'fs';7import * as path from 'path';8import { TestingCacheSalts } from '../../base/salts';9import { CacheScope } from '../../base/simulationContext';10import { ITestDiagnostic } from './diagnosticsProvider';11import { LintingDiagnosticsProvider } from './utils';1213/**14* Class which finds eslint diagnostic erors15*/16export class EslintDiagnosticsProvider extends LintingDiagnosticsProvider {1718override readonly id = 'eslint';19override readonly cacheSalt = TestingCacheSalts.eslintCacheSalt;20override readonly cacheScope = CacheScope.ESLint;2122private get eslintConfig(): any {23return {24'parser': '@typescript-eslint/parser',25'plugins': ['@typescript-eslint'],26'extends': [],27'parserOptions': {28'warnOnUnsupportedTypeScriptVersion': false,29'sourceType': 'module',30'ecmaVersion': 'latest',31'ecmaFeatures': { 'jsx': true, 'experimentalObjectRestSpread': true },32},33'ignorePatterns': ['!+'],34'rules': {35'constructor-super': 'error',36'for-direction': 'error',37'getter-return': 'error',38'no-async-promise-executor': 'error',39'no-class-assign': 'error',40'no-compare-neg-zero': 'error',41'no-cond-assign': 'error',42'no-const-assign': 'error',43'no-constant-condition': 'error',44'no-control-regex': 'error',45'no-dupe-args': 'error',46'no-empty-pattern': 'error',47'no-ex-assign': 'error',48'no-invalid-regexp': 'error',49'no-new-symbol': 'error',50'no-obj-calls': 'error',51'no-prototype-builtins': 'error',52'no-self-assign': 'error',53'no-setter-return': 'error',54'no-unreachable': 'error',55'no-unreachable-loop': 'error',56'no-unsafe-finally': 'error',57'no-unsafe-negation': 'error',58'no-unsafe-optional-chaining': 'error',59'use-isnan': 'error',60'indent': 'off'61},62};63}6465protected override async fetchCommand(temporaryDirectory: string, filePath: string) {66const eslintConfigFile = path.join(temporaryDirectory, '.eslintrc.json');67await fs.promises.writeFile(eslintConfigFile, JSON.stringify(this.eslintConfig));68return {69command: 'npx',70arguments: ['eslint', '--no-eslintrc', '--config', eslintConfigFile, '--no-ignore', '-f', 'json', filePath]71};72}7374protected override processDiagnostics(fileName: string, stdoutResult: any): ITestDiagnostic[] {75assert(Array.isArray(stdoutResult));76if (stdoutResult.length === 0) {77return [];78}79const sanitizeLineOrColumn = (lineOrColumn: any) => typeof lineOrColumn !== 'number' || Number.isNaN(lineOrColumn) ? 0 : Math.max(0, lineOrColumn - 1);80const diagnostics = [];81const messages = stdoutResult[0].messages;82assert(Array.isArray(messages));83for (const message of messages) {84const messageText = message.message;85assert(typeof messageText === 'string');86diagnostics.push({87file: fileName,88startLine: sanitizeLineOrColumn(message.line),89startCharacter: sanitizeLineOrColumn(message.column),90endLine: sanitizeLineOrColumn(message.endLine),91endCharacter: sanitizeLineOrColumn(message.endColumn),92message: messageText,93code: message.ruleId,94relatedInformation: undefined,95source: 'eslint'96});97}98return diagnostics;99}100}101102103