Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(website): rewrite WebLinter to typescript and fix support for ts 4.7 #5034

Merged
merged 8 commits into from May 24, 2022
4 changes: 2 additions & 2 deletions packages/utils/src/ts-eslint/Linter.ts
Expand Up @@ -76,7 +76,7 @@ declare class LinterBase {

/**
* Performs multiple autofix passes over the text until as many fixes as possible have been applied.
* @param text The source text to apply fixes to.
* @param code The source text to apply fixes to.
* @param config The ESLint config object to use.
* @param options The ESLint options object to use.
* @returns The result of the fix operation as returned from the SourceCodeFixer.
Expand Down Expand Up @@ -316,7 +316,7 @@ namespace Linter {

export interface ESLintParseResult {
ast: TSESTree.Program;
parserServices?: ParserServices;
services?: ParserServices;
armano2 marked this conversation as resolved.
Show resolved Hide resolved
scopeManager?: Scope.ScopeManager;
visitorKeys?: SourceCode.VisitorKeys;
}
Expand Down
92 changes: 0 additions & 92 deletions packages/website-eslint/src/linter/CompilerHost.js

This file was deleted.

74 changes: 8 additions & 66 deletions packages/website-eslint/src/linter/linter.js
@@ -1,74 +1,16 @@
import 'vs/language/typescript/tsWorker';
import { parseForESLint } from './parser';
import { Linter } from 'eslint';
import rules from '@typescript-eslint/eslint-plugin/dist/rules';

const PARSER_NAME = '@typescript-eslint/parser';

export function loadLinter(libs, options) {
export function createLinter() {
const linter = new Linter();
let storedAST;
let storedTsAST;
let storedScope;

let compilerOptions = options;

linter.defineParser(PARSER_NAME, {
parseForESLint(code, eslintOptions) {
const toParse = parseForESLint(
code,
eslintOptions,
compilerOptions,
libs,
);
storedAST = toParse.ast;
storedTsAST = toParse.tsAst;
storedScope = toParse.scopeManager;
return toParse;
},
// parse(code: string, options: ParserOptions): ParseForESLintResult['ast'] {
// const toParse = parseForESLint(code, options);
// storedAST = toParse.ast;
// return toParse.ast;
// },
});

for (const name of Object.keys(rules)) {
for (const name in rules) {
linter.defineRule(`@typescript-eslint/${name}`, rules[name]);
}

const ruleNames = Array.from(linter.getRules()).map(value => {
return {
name: value[0],
description: value[1]?.meta?.docs?.description,
};
});

return {
ruleNames: ruleNames,

updateOptions(options) {
compilerOptions = options || {};
},

getScope() {
return storedScope;
},

getAst() {
return storedAST;
},

getTsAst() {
return storedTsAST;
},

lint(code, parserOptions, rules) {
return linter.verify(code, {
parser: PARSER_NAME,
parserOptions,
rules,
});
},
};
return linter;
}

export { analyze } from '@typescript-eslint/scope-manager/dist/analyze';
armano2 marked this conversation as resolved.
Show resolved Hide resolved
export { visitorKeys } from '@typescript-eslint/visitor-keys/dist/visitor-keys';
armano2 marked this conversation as resolved.
Show resolved Hide resolved
export { astConverter } from '@typescript-eslint/typescript-estree/dist/ast-converter';
armano2 marked this conversation as resolved.
Show resolved Hide resolved
export { getScriptKind } from '@typescript-eslint/typescript-estree/dist/create-program/getScriptKind';
62 changes: 0 additions & 62 deletions packages/website-eslint/src/linter/parser.js

This file was deleted.

49 changes: 12 additions & 37 deletions packages/website-eslint/types/index.d.ts
@@ -1,38 +1,13 @@
import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
import type { ParserOptions } from '@typescript-eslint/types';
import type { SourceFile, CompilerOptions } from 'typescript';

export type LintMessage = TSESLint.Linter.LintMessage;
export type RuleFix = TSESLint.RuleFix;
export type RulesRecord = TSESLint.Linter.RulesRecord;
export type RuleEntry = TSESLint.Linter.RuleEntry;

export interface WebLinter {
ruleNames: { name: string; description?: string }[];

getAst(): TSESTree.Program;
getTsAst(): SourceFile;
getScope(): Record<string, unknown>;
updateOptions(options?: Record<string, unknown>): void;

lint(
code: string,
parserOptions: ParserOptions,
rules?: RulesRecord,
): LintMessage[];
import type { TSESLint } from '@typescript-eslint/utils';

import { analyze } from '@typescript-eslint/scope-manager/dist/analyze';
import { astConverter } from '@typescript-eslint/typescript-estree/dist/ast-converter';
import { getScriptKind } from '@typescript-eslint/typescript-estree/dist/create-program/getScriptKind';

export interface LintUtils {
createLinter: () => TSESLint.Linter;
analyze: typeof analyze;
visitorKeys: TSESLint.SourceCode.VisitorKeys;
astConverter: typeof astConverter;
getScriptKind: typeof getScriptKind;
}

export interface LinterLoader {
loadLinter(
libMap: Map<string, string>,
compilerOptions: CompilerOptions,
): WebLinter;
}

export type {
DebugLevel,
EcmaVersion,
ParserOptions,
SourceType,
TSESTree,
} from '@typescript-eslint/types';
2 changes: 1 addition & 1 deletion packages/website/src/components/ASTViewerESTree.tsx
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';

import ASTViewer from './ast/ASTViewer';
import type { ASTViewerBaseProps, ASTViewerModelMap } from './ast/types';
import type { TSESTree } from '@typescript-eslint/website-eslint';
import type { TSESTree } from '@typescript-eslint/utils';
import { serialize } from './ast/serializer/serializer';
import { createESTreeSerializer } from './ast/serializer/serializerESTree';

Expand Down
4 changes: 2 additions & 2 deletions packages/website/src/components/Playground.tsx
Expand Up @@ -17,7 +17,7 @@ import ASTViewerTS from './ASTViewerTS';

import type { RuleDetails, SelectedRange } from './types';

import type { TSESTree } from '@typescript-eslint/website-eslint';
import type { TSESTree } from '@typescript-eslint/utils';
import type { SourceFile } from 'typescript';
import ASTViewerScope from '@site/src/components/ASTViewerScope';

Expand All @@ -44,7 +44,7 @@ function Playground(): JSX.Element {
showAST: false,
sourceType: 'module',
code: '',
ts: process.env.TS_VERSION,
ts: process.env.TS_VERSION!,
rules: {},
tsConfig: {},
});
Expand Down
@@ -1,6 +1,6 @@
import type { ASTViewerModel, Serializer } from '../types';
import type { TSESTree } from '@typescript-eslint/utils';
import { isRecord } from '../utils';
import type { TSESTree } from '@typescript-eslint/website-eslint';

export const propsToFilter = ['parent', 'comments', 'tokens'];

Expand Down
@@ -1,5 +1,5 @@
import type { ASTViewerModel, Serializer, SelectedRange } from '../types';
import type { TSESTree } from '@typescript-eslint/website-eslint';
import type { TSESTree } from '@typescript-eslint/utils';
import { isRecord } from '../utils';

function isESTreeNode(
Expand Down
Expand Up @@ -20,6 +20,7 @@ export const propsToFilter = [
'jsDocComment',
'lineMap',
'externalModuleIndicator',
'setExternalModuleIndicator',
'bindDiagnostics',
'transformFlags',
'resolvedModules',
Expand Down
3 changes: 1 addition & 2 deletions packages/website/src/components/config/ConfigEslint.tsx
@@ -1,8 +1,7 @@
import React, { useCallback, useEffect, useState } from 'react';
import type { RulesRecord, RuleEntry } from '@typescript-eslint/website-eslint';

import ConfigEditor, { ConfigOptionsType } from './ConfigEditor';
import type { RuleDetails } from '../types';
import type { RuleDetails, RulesRecord, RuleEntry } from '../types';
import { shallowEqual } from '../lib/shallowEqual';

export interface ModalEslintProps {
Expand Down
10 changes: 5 additions & 5 deletions packages/website/src/components/editor/LoadedEditor.tsx
@@ -1,12 +1,12 @@
import React, { useMemo } from 'react';
import type Monaco from 'monaco-editor';
import { useEffect, useRef, useState } from 'react';
import type { WebLinter } from '@typescript-eslint/website-eslint';
import type { SandboxInstance } from './useSandboxServices';
import type { CommonEditorProps } from './types';
import type { WebLinter } from '../linter/WebLinter';

import { debounce } from '../lib/debounce';
import { lintCode, LintCodeAction } from './lintCode';
import { lintCode, LintCodeAction } from '../linter/lintCode';
import { createProvideCodeActions } from './createProvideCodeActions';

export interface LoadedEditorProps extends CommonEditorProps {
Expand Down Expand Up @@ -83,9 +83,9 @@ export const LoadedEditor: React.FC<LoadedEditorProps> = ({
);
}

onEsASTChange(fatalMessage ?? webLinter.getAst());
onTsASTChange(fatalMessage ?? webLinter.getTsAst());
onScopeChange(fatalMessage ?? webLinter.getScope());
onEsASTChange(fatalMessage ?? webLinter.storedAST ?? '');
onTsASTChange(fatalMessage ?? webLinter.storedTsAST ?? '');
onScopeChange(fatalMessage ?? webLinter.storedScope ?? '');
onSelect(sandboxInstance.editor.getPosition());
}, 500),
[code, jsx, sandboxInstance, rules, sourceType, tsConfig, webLinter],
Expand Down