Skip to content

Commit 09678af

Browse files
committed
feat(method-snippets): enable constructor call snippet when in new expression
1 parent 0a6f17f commit 09678af

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

typescript/src/constructMethodSnippet.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
1-
import { compact } from '@zardoy/utils'
1+
import { compact, oneOf } from '@zardoy/utils'
22
import { isTypeNode } from './completions/keywordsSpace'
33
import { GetConfig } from './types'
44
import { findChildContainingExactPosition } from './utils'
55

66
export default (languageService: ts.LanguageService, sourceFile: ts.SourceFile, position: number, c: GetConfig) => {
7-
const node = findChildContainingExactPosition(sourceFile, position)
7+
let node = findChildContainingExactPosition(sourceFile, position)
88
if (!node || isTypeNode(node)) return
99

1010
const checker = languageService.getProgram()!.getTypeChecker()!
1111
const type = checker.getTypeAtLocation(node)
12-
const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call)
12+
13+
if (ts.isIdentifier(node)) node = node.parent
14+
if (ts.isPropertyAccessExpression(node)) node = node.parent
15+
16+
const isNewExpression = ts.isNewExpression(node)
17+
const signatures = checker.getSignaturesOfType(type, isNewExpression ? ts.SignatureKind.Construct : ts.SignatureKind.Call)
18+
// ensure node is not used below
1319
if (signatures.length === 0) return
14-
const signature = signatures[0]
20+
const signature = signatures[0]!
21+
// probably need to remove check as class can be instantiated inside another class, and don't really see a reason for this check
22+
if (isNewExpression && hasPrivateOrProtectedModifier(signature.getDeclaration().modifiers)) return
1523
if (signatures.length > 1 && c('methodSnippets.multipleSignatures') === 'empty') {
1624
return ['']
1725
}
@@ -121,3 +129,7 @@ function getPromiseLikeTypeArgument(type: ts.Type | undefined, checker: ts.TypeC
121129
if (typeArgs.length !== 1) return
122130
return typeArgs[0]!
123131
}
132+
133+
function hasPrivateOrProtectedModifier(modifiers: ts.NodeArray<ts.ModifierLike> | ts.NodeArray<ts.Modifier> | undefined) {
134+
return modifiers?.some(modifier => oneOf(modifier.kind, ts.SyntaxKind.PrivateKeyword, ts.SyntaxKind.ProtectedKeyword))
135+
}

typescript/test/completions.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,25 @@ describe('Method snippets', () => {
171171
compareMethodSnippetAgainstMarker(markers, 6, '(a, b, c)')
172172
})
173173

174+
test('Class', () => {
175+
const [, _, markers] = fileContentsSpecialPositions(/* ts */ `
176+
class A {
177+
constructor(a) {}
178+
}
179+
180+
class B {
181+
protected constructor(a) {}
182+
}
183+
184+
new A/*1*/
185+
// not sure...
186+
new B/*2*/
187+
`)
188+
189+
compareMethodSnippetAgainstMarker(markers, 1, ['a'])
190+
compareMethodSnippetAgainstMarker(markers, 2, null)
191+
})
192+
174193
test('Skip trailing void', () => {
175194
const [, _, markers] = fileContentsSpecialPositions(/* ts */ `
176195
new Promise<void>((resolve) => {

0 commit comments

Comments
 (0)