Skip to content

Commit

Permalink
feat: include fix for builtin `typescript.suggest.completeFunctionCal…
Browse files Browse the repository at this point in the history
…ls` in some positions out of the box

fix: don't insert method snippet in some positions, inclusing const assigning
  • Loading branch information
zardoy committed Sep 11, 2022
1 parent 8f3280f commit f96835e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
6 changes: 6 additions & 0 deletions typescript/src/completionsAtPosition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as emmet from '@vscode/emmet-helper'
import isInBannedPosition from './isInBannedPosition'
import { GetConfig } from './types'
import { findChildContainingPosition } from './utils'
import { isGoodPositionBuiltinMethodCompletion } from './isGootPositionMethodCompletion'

export type PrevCompletionMap = Record<string, { originalName?: string; documentationOverride?: string | tslib.SymbolDisplayPart[] }>

Expand Down Expand Up @@ -225,6 +226,11 @@ export const getCompletionsAtPosition = (
if (rule.patch?.insertText) suggestion.isSnippet = true
}

// prevent vscode-builtin wrong insertText with methods snippets enabled
if (!isGoodPositionBuiltinMethodCompletion(ts, sourceFile, position)) {
prior.entries = prior.entries.map(item => ({ ...item, insertText: item.insertText ?? item.name, isSnippet: true }))
}

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, {})))
Expand Down
5 changes: 3 additions & 2 deletions typescript/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import type { Configuration } from '../../src/configurationType'
import _ from 'lodash'
import { GetConfig } from './types'
import { getCompletionsAtPosition, PrevCompletionMap } from './completionsAtPosition'
import { CompletionEntry } from 'typescript/lib/tsserverlibrary'
import { getParameterListParts } from './completionGetMethodParameters'
import { oneOf } from '@zardoy/utils'
import { isGoodPositionMethodCompletion } from './isGootPositionMethodCompletion'

const thisPluginMarker = Symbol('__essentialPluginsMarker__')

Expand Down Expand Up @@ -87,8 +87,9 @@ export = function ({ typescript }: { typescript: typeof import('typescript/lib/t
)
if (!prior) return
if (c('enableMethodSnippets') && oneOf(prior.kind as string, ts.ScriptElementKind.constElement, 'property')) {
const goodPosition = isGoodPositionMethodCompletion(ts, fileName, sourceFile, position, info.languageService)
const punctuationIndex = prior.displayParts.findIndex(({ kind }) => kind === 'punctuation')
if (punctuationIndex !== 1) {
if (goodPosition && punctuationIndex !== 1) {
const isParsableMethod = prior.displayParts
// next is space
.slice(punctuationIndex + 2)
Expand Down
32 changes: 32 additions & 0 deletions typescript/src/isGootPositionMethodCompletion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type tslib from 'typescript/lib/tsserverlibrary'
import { findChildContainingPosition } from './utils'

export const isGoodPositionBuiltinMethodCompletion = (ts: typeof tslib, sourceFile: tslib.SourceFile, position: number) => {
const importClauseCandidate = findChildContainingPosition(ts, sourceFile, position, 2)
if (importClauseCandidate?.kind === 266) return false
const currentNode = findChildContainingPosition(ts, sourceFile, position)
// const obj = { method() {}, arrow: () => {} }
// type A = typeof obj["|"]
if (currentNode && ts.isStringLiteralLike(currentNode)) return false
return true
}

export const isGoodPositionMethodCompletion = (
ts: typeof tslib,
fileName: string,
sourceFile: tslib.SourceFile,
position: number,
languageService: tslib.LanguageService,
) => {
if (!isGoodPositionBuiltinMethodCompletion(ts, sourceFile, position)) return false
const { kind } = languageService.getQuickInfoAtPosition(fileName, position) ?? {}
switch (kind) {
case 'var':
case 'let':
case 'const':
case 'alias':
return false
}
// TODO check for brace here
return true
}
7 changes: 6 additions & 1 deletion typescript/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ export function findChildContainingPosition(
typescript: typeof import('typescript/lib/tsserverlibrary'),
sourceFile: tslib.SourceFile,
position: number,
maxDepth?: number,
): tslib.Node | undefined {
let currentDepth = 0
function find(node: ts.Node): ts.Node | undefined {
if (position >= node.getStart() && position < node.getEnd()) return typescript.forEachChild(node, find) || node
if (position >= node.getStart() && position < node.getEnd()) {
if (++currentDepth === maxDepth) return node
return typescript.forEachChild(node, find) || node
}

return
}
Expand Down

0 comments on commit f96835e

Please sign in to comment.