Skip to content

Commit 22f43df

Browse files
committed
fix: make fixPropertiesSorting feature work almost everywhere (all known problems fixed)
1 parent a3a023b commit 22f43df

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

typescript/src/completions/fixPropertiesSorting.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { oneOf } from '@zardoy/utils'
2-
import { groupBy, partition } from 'rambda'
2+
import { partition } from 'rambda'
3+
import { getAllPropertiesOfType } from './objectLiteralCompletions'
4+
import { sharedCompletionContext } from './sharedContext'
35

4-
export default (entries: ts.CompletionEntry[], node: ts.Node | undefined, sourceFile: ts.SourceFile, program: ts.Program) => {
6+
export default (entries: ts.CompletionEntry[]) => {
7+
const { node, program, c } = sharedCompletionContext
8+
if (!c('fixSuggestionsSorting')) return
59
if (!node) return
610
// if (ts.isObjectLiteralExpression(node) && ts.isCallExpression(node.parent)) {
711
// const typeChecker = program.getTypeChecker()
@@ -10,6 +14,7 @@ export default (entries: ts.CompletionEntry[], node: ts.Node | undefined, source
1014
// }
1115
let rightNode: ts.Node | undefined
1216
const upperNode = ts.isIdentifier(node) ? node.parent : node
17+
if (ts.isObjectLiteralExpression(node)) rightNode = node
1318
if (ts.isPropertyAccessExpression(upperNode)) rightNode = upperNode.expression
1419
else if (ts.isObjectBindingPattern(node)) {
1520
if (ts.isVariableDeclaration(node.parent)) {
@@ -25,8 +30,8 @@ export default (entries: ts.CompletionEntry[], node: ts.Node | undefined, source
2530
}
2631
if (!rightNode) return
2732
const typeChecker = program.getTypeChecker()
28-
const type = typeChecker.getTypeAtLocation(rightNode)
29-
const sourceProps = type.getProperties?.()?.map(({ name }) => name)
33+
const type = typeChecker.getContextualType(rightNode as ts.Expression) ?? typeChecker.getTypeAtLocation(rightNode)
34+
const sourceProps = getAllPropertiesOfType(type, typeChecker)?.map(({ name }) => name)
3035
// languageService.getSignatureHelpItems(fileName, position, {}))
3136
if (!sourceProps) return
3237
// const entriesBySortText = groupBy(({ sortText }) => sortText, entries)

typescript/src/completions/objectLiteralCompletions.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,7 @@ export default (
2020
const typeChecker = languageService.getProgram()!.getTypeChecker()!
2121
const objType = typeChecker.getContextualType(node)
2222
if (!objType) return
23-
const types = objType.isUnion() ? objType.types : [objType]
24-
const properties = types
25-
.flatMap(type => {
26-
if (isFunctionType(type, typeChecker)) return []
27-
if (isObjectCompletion(type, typeChecker)) return typeChecker.getPropertiesOfType(type)
28-
return []
29-
})
30-
.filter((property, i, arr) => {
31-
return !arr.find(({ name }, k) => name === property.name && i !== k)
32-
})
23+
const properties = getAllPropertiesOfType(objType, typeChecker)
3324
for (const property of properties) {
3425
const entry = entries.find(({ name }) => name === property.name)
3526
if (!entry) continue
@@ -136,3 +127,23 @@ const isObjectCompletion = (type: ts.Type, checker: ts.TypeChecker) => {
136127
if (type.isUnion()) return isEverySubtype(type, type => isObjectCompletion(type, checker))
137128
return false
138129
}
130+
131+
export const getAllPropertiesOfType = (type: ts.Type, typeChecker: ts.TypeChecker) => {
132+
const types = type.isUnion() ? type.types : [type]
133+
let objectCount = 0
134+
const properties = types
135+
.flatMap(type => {
136+
if (isFunctionType(type, typeChecker)) return []
137+
if (isObjectCompletion(type, typeChecker)) {
138+
objectCount++
139+
return typeChecker.getPropertiesOfType(type)
140+
}
141+
return []
142+
})
143+
.filter((property, i, arr) => {
144+
// perf
145+
if (objectCount === 1) return true
146+
return !arr.find(({ name }, k) => name === property.name && i !== k)
147+
})
148+
return properties
149+
}

typescript/src/completionsAtPosition.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export const getCompletionsAtPosition = (
169169
}
170170
}
171171

172-
if (c('fixSuggestionsSorting')) prior.entries = fixPropertiesSorting(prior.entries, leftNode, sourceFile, program) ?? prior.entries
172+
prior.entries = fixPropertiesSorting(prior.entries) ?? prior.entries
173173
if (node) prior.entries = boostKeywordSuggestions(prior.entries, position, node) ?? prior.entries
174174

175175
const entryNames = new Set(prior.entries.map(({ name }) => name))

0 commit comments

Comments
 (0)