From 36c17f05441de05aa0b8d8112017bc4c96c1fa48 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Thu, 19 May 2022 04:29:53 +0300 Subject: [PATCH] refactor: fix some eslint errors in typescript fix: don't patch text suggestios on functions & static classes functions --- src/configurationType.ts | 2 +- src/configurationTypeCache.jsonc | 3 +- src/extension.ts | 1 + typescript/src/index.ts | 68 ++++++++++++++++---------------- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/configurationType.ts b/src/configurationType.ts index 32768fa2..a9a509cf 100644 --- a/src/configurationType.ts +++ b/src/configurationType.ts @@ -3,7 +3,7 @@ import { ScriptElementKind } from 'typescript/lib/tsserverlibrary' type ReplaceRule = { /** e.g. `readFile`, `^readFile` (global) or `fs.readFile` */ suggestion: string - filter: { + filter?: { // package?: string // TODO kind?: keyof typeof ScriptElementKind diff --git a/src/configurationTypeCache.jsonc b/src/configurationTypeCache.jsonc index 175dc83a..d4c73b2f 100644 --- a/src/configurationTypeCache.jsonc +++ b/src/configurationTypeCache.jsonc @@ -1,5 +1,5 @@ // GENERATED. DON'T EDIT MANUALLY -// md5hash: 9c3812628516e353f3aa75256e99e8fa +// md5hash: 0b8b4697ce68ebfe40346fd51700a786 { "type": "object", "properties": { @@ -219,7 +219,6 @@ } }, "required": [ - "filter", "suggestion" ] } diff --git a/src/extension.ts b/src/extension.ts index 1b01c951..958adc26 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -16,6 +16,7 @@ export const activate = async () => { const config = vscode.workspace.getConfiguration().get(process.env.IDS_PREFIX!) api.configurePlugin('ts-essential-plugins', config) } + vscode.workspace.onDidChangeConfiguration(({ affectsConfiguration }) => { if (affectsConfiguration(process.env.IDS_PREFIX!)) syncConfig() }) diff --git a/typescript/src/index.ts b/typescript/src/index.ts index d646c5d5..065228ba 100644 --- a/typescript/src/index.ts +++ b/typescript/src/index.ts @@ -2,10 +2,11 @@ import get from 'lodash.get' import type tslib from 'typescript/lib/tsserverlibrary' import * as emmet from '@vscode/emmet-helper' +// eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore import type { Configuration } from '../../src/configurationType' -export = function ({ typescript }: { typescript: typeof import('typescript/lib/tsserverlibrary') }) { +export = function({ typescript }: { typescript: typeof import('typescript/lib/tsserverlibrary') }) { const ts = typescript let _configuration: Configuration const c = (key: T): Configuration[T] => get(_configuration, key) @@ -42,11 +43,11 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t } let prevCompletionsMap: Record + // eslint-disable-next-line complexity proxy.getCompletionsAtPosition = (fileName, position, options) => { prevCompletionsMap = {} - if (!_configuration) { - console.log('no received configuration!') - } + if (!_configuration) console.log('no received configuration!') + // console.time('slow-down') const program = info.languageService.getProgram() const sourceFile = program?.getSourceFile(fileName) @@ -79,13 +80,13 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t if (lastPart.startsWith('<')) lastPart = lastPart.slice(1) const isStartingWithUpperCase = (str: string) => str[0] === str[0]?.toUpperCase() // check if starts with lowercase - if (isStartingWithUpperCase(lastPart)) { + if (isStartingWithUpperCase(lastPart)) // TODO! compare with suggestions from lib.dom prior.entries = prior.entries.filter( entry => isStartingWithUpperCase(entry.name) && ![typescript.ScriptElementKind.enumElement].includes(entry.kind), ) - } } + if ( c('jsxEmmet.type') !== 'disabled' && (emmetSyntaxKinds.includes(node.kind) || @@ -121,7 +122,7 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t 'html', {}, ) ?? { items: [] } - for (const completion of emmetCompletions.items) { + for (const completion of emmetCompletions.items) prior.entries.push({ kind: typescript.ScriptElementKind.label, name: completion.label.slice(1), @@ -132,7 +133,6 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t sourceDisplay: completion.detail !== undefined ? [{ kind: 'text', text: completion.detail }] : undefined, // replacementSpan: { start: position - 5, length: 5 }, }) - } } else { const tags = c('jsxPseudoEmmet.tags') for (let [tag, value] of Object.entries(tags)) { @@ -149,9 +149,9 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t } } } - if (!prior) { - return - } + + if (!prior) return + // const fullText = scriptSnapshot.getText(0, scriptSnapshot.getLength()) // const matchImport = /(import (.*)from )['"].*['"]/.exec(fullText.split('\n')[line]!)?.[1] // if (matchImport && character <= `import${matchImport}`.length) { @@ -160,14 +160,13 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t // } // prior.isGlobalCompletion // prior.entries[0] - const entryNames = prior.entries.map(({ name }) => name) + const entryNames = new Set(prior.entries.map(({ name }) => name)) if (c('removeUselessFunctionProps.enable')) prior.entries = prior.entries.filter(e => !['Symbol', 'caller', 'prototype'].includes(e.name)) - if (['bind', 'call', 'caller'].every(name => entryNames.includes(name))) { - if (c('highlightNonFunctionMethods.enable')) { - const standardProps = ['Symbol', 'apply', 'arguments', 'bind', 'call', 'caller', 'length', 'name', 'prototype', 'toString'] + if (['bind', 'call', 'caller'].every(name => entryNames.has(name)) && c('highlightNonFunctionMethods.enable')) { + const standardProps = new Set(['Symbol', 'apply', 'arguments', 'bind', 'call', 'caller', 'length', 'name', 'prototype', 'toString']) // TODO lift up! prior.entries = prior.entries.map(entry => { - if (!standardProps.includes(entry.name)) { + if (!standardProps.has(entry.name) && entry.kind !== ts.ScriptElementKind.warning) { const newName = `☆${entry.name}` prevCompletionsMap[newName] = { originalName: entry.name, @@ -178,28 +177,30 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t name: newName, } } + return entry }) } - } + if (c('patchToString.enable')) { // const indexToPatch = arrayMoveItemToFrom( // prior.entries, // ({ name }) => name === 'toExponential', // ({ name }) => name === 'toString', // ) - let indexToPatch = prior.entries.findIndex(({ name }) => name === 'toString') + const indexToPatch = prior.entries.findIndex(({ name }) => name === 'toString') if (indexToPatch !== -1) { prior.entries[indexToPatch]!.insertText = `${prior.entries[indexToPatch]!.insertText ?? prior.entries[indexToPatch]!.name}()` prior.entries[indexToPatch]!.kind = typescript.ScriptElementKind.constElement // prior.entries[indexToPatch]!.isSnippet = true } } + const banAutoImportPackages = c('suggestions.banAutoImportPackages') if (banAutoImportPackages?.length) prior.entries = prior.entries.filter(entry => { if (!entry.sourceDisplay) return true - const text = entry.sourceDisplay.map(item => item.text).join() + const text = entry.sourceDisplay.map(item => item.text).join('') if (text.startsWith('.')) return true // TODO change to startsWith? return !banAutoImportPackages.includes(text) @@ -214,20 +215,20 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t }) if (!suggestion) continue - if (rule.delete) { + if (rule.delete) prior.entries.splice(foundIndex!, 1) - } - if (rule.duplicateOriginal) { + + if (rule.duplicateOriginal) prior.entries.splice(rule.duplicateOriginal === 'above' ? foundIndex! : foundIndex! + 1, 0, { ...suggestion }) - } Object.assign(suggestion, rule.patch ?? {}) if (rule.patch?.insertText) suggestion.isSnippet = true } - if (c('correctSorting.enable')) { + + if (c('correctSorting.enable')) prior.entries = prior.entries.map((entry, index) => ({ ...entry, sortText: `${entry.sortText ?? ''}${index}` })) - } + // console.log('signatureHelp', JSON.stringify(info.languageService.getSignatureHelpItems(fileName, position, {}))) // console.timeEnd('slow-down') return prior @@ -265,6 +266,7 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t return prior } + proxy.getCodeFixesAtPosition = (fileName, start, end, errorCodes, formatOptions, preferences) => { let prior = info.languageService.getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences) @@ -278,11 +280,12 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t return prior } - // @ts-expect-error + + // @ts-expect-error some experiments proxy.ignored = (fileName: string, positionOrRange: number, preferences: any) => { - if (typeof positionOrRange !== 'number') { + if (typeof positionOrRange !== 'number') positionOrRange = positionOrRange - } + // ts.createSourceFile(fileName, sourceText, languageVersion) const { textSpan } = proxy.getSmartSelectionRange(fileName, positionOrRange) console.log('textSpan.start', textSpan.start, textSpan.length) @@ -298,6 +301,7 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t console.log('no node') return [] } + // console.log( // 'special 1', // typescript.isJsxExpression(node), @@ -339,9 +343,7 @@ const arrayMoveItemToFrom = (array: T[], originalItem: ArrayPredicate, ite return originalItemIndex } -const patchText = (input: string, start: number, end: number, newText: string) => { - return input.slice(0, start) + newText + input.slice(end) -} +const patchText = (input: string, start: number, end: number, newText: string) => input.slice(0, start) + newText + input.slice(end) function findChildContainingPosition( typescript: typeof import('typescript/lib/tsserverlibrary'), @@ -349,9 +351,9 @@ function findChildContainingPosition( position: number, ): tslib.Node | undefined { function find(node: ts.Node): ts.Node | undefined { - if (position >= node.getStart() && position < node.getEnd()) { + if (position >= node.getStart() && position < node.getEnd()) return typescript.forEachChild(node, find) || node - } + return } return find(sourceFile)