Skip to content

Commit

Permalink
feat: add jsDoc typecast completions, add tests (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ilanaya authored Oct 29, 2023
1 parent 44e45b1 commit b3d80d8
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 28 deletions.
26 changes: 0 additions & 26 deletions typescript/src/completions/asSuggestions.ts

This file was deleted.

40 changes: 40 additions & 0 deletions typescript/src/completions/typecastCompletions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { findChildContainingExactPosition } from '../utils'
import { sharedCompletionContext } from './sharedContext'

const getCastedTypeCompletionEntry = (typeChecker: ts.TypeChecker, node: ts.Expression) => {
const typeAtLocation = typeChecker.getTypeAtLocation(node)
const type = typeChecker.typeToString(typeAtLocation)
const widenType = typeChecker.typeToString(typeChecker.getBaseTypeOfLiteralType(typeAtLocation))

return {
kind: ts.ScriptElementKind.unknown,
name: type === widenType ? type : widenType,
sortText: '!',
}
}

export default () => {
const typeChecker = sharedCompletionContext.program.getTypeChecker()
const { position, fullText, prior } = sharedCompletionContext

// as completions
if (fullText.slice(0, position - 1).endsWith('as')) {
const node = findChildContainingExactPosition(sharedCompletionContext.sourceFile, position - 2)
if (!node || !ts.isAsExpression(node)) return
const entry = getCastedTypeCompletionEntry(typeChecker, node.expression)
prior.entries.push(entry)
return
}

// jsdoc typecast completions
const node = findChildContainingExactPosition(sharedCompletionContext.sourceFile, position)
if (!node) return
let typeCastedNode: ts.ParenthesizedExpression | undefined
node.forEachChild(node => {
if (ts.isParenthesizedExpression(node) && ts.getJSDocTypeTag(node)) typeCastedNode = node
})

if (!typeCastedNode) return
const entry = getCastedTypeCompletionEntry(typeChecker, typeCastedNode.expression)
prior.entries.push(entry)
}
4 changes: 2 additions & 2 deletions typescript/src/completionsAtPosition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import stringTemplateTypeCompletions from './completions/stringTemplateType'
import localityBonus from './completions/localityBonus'
import functionCompletions from './completions/functionCompletions'
import staticHintSuggestions from './completions/staticHintSuggestions'
import asSuggestions from './completions/asSuggestions'
import typecastCompletions from './completions/typecastCompletions'

export type PrevCompletionMap = Record<
string,
Expand Down Expand Up @@ -300,7 +300,7 @@ export const getCompletionsAtPosition = (
if (c('improveJsxCompletions') && leftNode) prior.entries = improveJsxCompletions(prior.entries, leftNode, position, sourceFile, c('jsxCompletionsMap'))

prior.entries = localityBonus(prior.entries) ?? prior.entries
asSuggestions()
typecastCompletions()
prior.entries.push(...(staticHintSuggestions() ?? []))

const processedEntries = new Set<ts.CompletionEntry>()
Expand Down
20 changes: 20 additions & 0 deletions typescript/test/completions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -860,3 +860,23 @@ test('In Keyword Completions', () => {
}
`)
})
describe('Typecast completions', () => {
test('As completions', () => {
const [pos] = newFileContents(/*ts*/ `
const b = 5
const a = b as /*|*/
`)
const completions = getCompletionsAtPosition(pos!)?.entriesSorted

expect(completions?.[0]?.name).toEqual('number')
})
test('jsDoc typecast', () => {
const [pos] = newFileContents(/*ts*/ `
const b = 5
const a = /** @type {/*|*/} */(b)
`)
const completions = getCompletionsAtPosition(pos!)?.entriesSorted

expect(completions?.[0]?.name).toEqual('number')
})
})

0 comments on commit b3d80d8

Please sign in to comment.