Skip to content

Commit a8431d3

Browse files
authored
Merge pull request #127 from zardoy/develop
2 parents df3bb76 + 7c8879f commit a8431d3

File tree

8 files changed

+74
-29
lines changed

8 files changed

+74
-29
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
"@types/mocha": "^9.1.1",
147147
"@types/pluralize": "^0.0.29",
148148
"@volar/language-server": "1.3.0-alpha.3",
149-
"@volar/language-service": "1.3.0-alpha.3",
149+
"@volar/language-service": "1.5.0",
150150
"@volar/vue-language-core": "^1.2.0-patch.2",
151151
"@vscode/emmet-helper": "^2.8.4",
152152
"@vscode/test-electron": "^2.1.5",

pnpm-lock.yaml

Lines changed: 36 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/vueVolarSupport.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,24 @@ export default () => {
66
if (process.env.PLATFORM !== 'node') return
77
const handler = () => {
88
const config = vscode.workspace.getConfiguration('')
9-
if (
10-
!getExtensionSetting('enableVueSupport') ||
11-
!vscode.extensions.getExtension('Vue.volar') ||
12-
isConfigValueChanged('volar.vueserver.configFilePath')
13-
) {
9+
const VOLAR_CONFIG_FILE_SETTING = 'vue.server.configFilePath'
10+
if (!getExtensionSetting('enableVueSupport') || !vscode.extensions.getExtension('Vue.volar') || isConfigValueChanged(VOLAR_CONFIG_FILE_SETTING)) {
1411
return
1512
}
1613

17-
void config.update('volar.vueserver.configFilePath', extensionCtx.asAbsolutePath('./volarConfig.js'), vscode.ConfigurationTarget.Global)
14+
void config.update(VOLAR_CONFIG_FILE_SETTING, extensionCtx.asAbsolutePath('./volarConfig.js'), vscode.ConfigurationTarget.Global)
1815
}
1916

2017
handler()
2118
watchExtensionSettings(['enableVueSupport'], handler)
2219
vscode.extensions.onDidChange(handler)
2320
}
2421

25-
const isConfigValueChanged = (id: string) => {
22+
const isConfigValueChanged = (settingId: string) => {
2623
if (process.env.PLATFORM !== 'web') {
2724
const config = vscode.workspace.getConfiguration('')
28-
const userValue = config.get<string>(id)
29-
if (userValue === config.inspect(id)!.defaultValue) return false
25+
const userValue = config.get<string>(settingId)
26+
if (userValue === config.inspect(settingId)!.defaultValue) return false
3027
// means that value was set by us programmatically, let's update it
3128
// eslint-disable-next-line @typescript-eslint/no-require-imports
3229
if (userValue?.startsWith(require('path').join(extensionCtx.extensionPath, '../..'))) return false

typescript/src/completions/functionCompletions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export default (entries: ts.CompletionEntry[]) => {
77
const { languageService, c, sourceFile, position } = sharedCompletionContext
88

99
const methodSnippetInsertTextMode = c('methodSnippetsInsertText')
10-
const enableResolvingInsertText = c('enableMethodSnippets') && methodSnippetInsertTextMode !== 'disable'
10+
const nextChar = sourceFile.getFullText().slice(position, position + 1)
11+
const enableResolvingInsertText = !['(', '.', '`'].includes(nextChar) && c('enableMethodSnippets') && methodSnippetInsertTextMode !== 'disable'
1112
const changeKindToFunction = c('experiments.changeKindToFunction')
1213

1314
if (!enableResolvingInsertText && !changeKindToFunction) return

typescript/src/constructMethodSnippet.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ export default (
1919
if (!containerNode || isTypeNode(containerNode)) return
2020

2121
const checker = languageService.getProgram()!.getTypeChecker()!
22-
const type = symbol ? checker.getTypeOfSymbol(symbol) : checker.getTypeAtLocation(containerNode)
22+
let type = symbol ? checker.getTypeOfSymbol(symbol) : checker.getTypeAtLocation(containerNode)
23+
// give another chance
24+
if (symbol && type['intrinsicName'] === 'error') type = checker.getTypeOfSymbolAtLocation(symbol, containerNode)
2325

2426
if (ts.isIdentifier(containerNode)) containerNode = containerNode.parent
2527
if (ts.isPropertyAccessExpression(containerNode)) containerNode = containerNode.parent
2628

27-
const isNewExpression = ts.isNewExpression(containerNode)
29+
const isNewExpression =
30+
ts.isNewExpression(containerNode) &&
31+
ts.textSpanIntersectsWithPosition(ts.createTextSpanFromBounds(containerNode.expression.pos, containerNode.expression.end), position)
2832
if (!isNewExpression && (type.getProperties().length > 0 || type.getStringIndexType() || type.getNumberIndexType())) {
2933
resolveData.isAmbiguous = true
3034
}
@@ -34,7 +38,7 @@ export default (
3438
if (signatures.length === 0) return
3539
const signature = signatures[0]!
3640
// probably need to remove check as class can be instantiated inside another class, and don't really see a reason for this check
37-
if (isNewExpression && hasPrivateOrProtectedModifier((signature.getDeclaration() as ts.ConstructorDeclaration).modifiers)) return
41+
if (isNewExpression && hasPrivateOrProtectedModifier((signature.getDeclaration() as ts.ConstructorDeclaration | undefined)?.modifiers)) return
3842
if (signatures.length > 1 && c('methodSnippets.multipleSignatures') === 'empty') {
3943
return ['']
4044
}

typescript/src/volarConfig.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
// will be required from ./node_modules/typescript-essential-plugins/index.js
33
const originalPluginFactory = require('typescript-essential-plugins')
44

5-
const plugin = (context => {
5+
const plugin = ((context, { typescript: tsModule } = {}) => {
6+
if (!context) throw new Error('Not recieve context')
67
const { typescript } = context
7-
let configurationHost = context.configurationHost!
8-
configurationHost ??= context['env'].configurationHost
8+
let configurationHost = context.env
9+
if (context['configurationHost']!) configurationHost = context['configurationHost']!
910
const patchConfig = config => {
1011
return {
1112
...config,
@@ -17,13 +18,14 @@ const plugin = (context => {
1718
}
1819

1920
if (typescript && configurationHost) {
21+
const ts = tsModule ?? typescript['module']
2022
const plugin = originalPluginFactory({
21-
typescript: typescript.module,
23+
typescript: ts,
2224
})
2325
// todo support vue-specific settings
2426
const originalLsMethods = { ...typescript.languageService }
2527

26-
void configurationHost.getConfiguration<any>('tsEssentialPlugins').then(_configuration => {
28+
void configurationHost.getConfiguration!<any>('tsEssentialPlugins').then(_configuration => {
2729
// if (typescript.languageService[thisPluginMarker]) return
2830
const config = patchConfig(_configuration)
2931
if (!config.enablePlugin) return
@@ -39,8 +41,8 @@ const plugin = (context => {
3941
}
4042
})
4143

42-
configurationHost.onDidChangeConfiguration(() => {
43-
void configurationHost.getConfiguration<any>('tsEssentialPlugins').then(config => {
44+
configurationHost.onDidChangeConfiguration!(() => {
45+
void configurationHost.getConfiguration!<any>('tsEssentialPlugins').then(config => {
4446
config = patchConfig(config)
4547
plugin.onConfigurationChanged?.(config)
4648
// temporary workaround
@@ -54,17 +56,17 @@ const plugin = (context => {
5456
console.warn('Failed to activate tsEssentialPlugins, because of no typescript or configurationHost context')
5557
}
5658
return {}
57-
}) satisfies import('@volar/language-service').LanguageServicePlugin
59+
}) satisfies import('@volar/language-service').Service
5860

5961
module.exports = {
6062
plugins: [
61-
c => {
63+
(...args) => {
6264
try {
63-
return plugin(c)
65+
return plugin(...(args as [any]))
6466
} catch (err) {
6567
console.log('TS Essentials error', err)
6668
return {}
6769
}
6870
},
6971
],
70-
}
72+
} /* satisfies import('@volar/language-service').ServiceContext */

typescript/test/completions.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ describe('Method snippets', () => {
137137
function foo(this: {}) {}
138138
foo/*3*/
139139
140+
// new class
141+
new Something(foo/*301*/)
142+
140143
// contextual type
141144
declare const bar: {
142145
b: (a) => {}
@@ -173,6 +176,7 @@ describe('Method snippets', () => {
173176
compareMethodSnippetAgainstMarker(markers, 1, null)
174177
compareMethodSnippetAgainstMarker(markers, 2, '()')
175178
compareMethodSnippetAgainstMarker(markers, 3, '(a)')
179+
compareMethodSnippetAgainstMarker(markers, 301, '(a)')
176180
compareMethodSnippetAgainstMarker(markers, 4, '($b)')
177181
compareMethodSnippetAgainstMarker(markers, 5, '(a, b, { d, e: {} }, ...c)')
178182
compareMethodSnippetAgainstMarker(markers, 6, '(a, b, c)')
@@ -188,13 +192,17 @@ describe('Method snippets', () => {
188192
protected constructor(a) {}
189193
}
190194
195+
class C {}
196+
191197
new A/*1*/
192198
// not sure...
193199
new B/*2*/
200+
new C/*3*/
194201
`)
195202

196203
compareMethodSnippetAgainstMarker(markers, 1, ['a'])
197204
compareMethodSnippetAgainstMarker(markers, 2, null)
205+
compareMethodSnippetAgainstMarker(markers, 3, [])
198206
})
199207

200208
test('Skip trailing void', () => {

typescript/test/testing.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export const fourslashLikeTester = (contents: string, fileName = entrypoint) =>
138138
export const fileContentsSpecialPositions = (contents: string, fileName = entrypoint) => {
139139
const cursorPositions: [number[], number[], number[]] = [[], [], []]
140140
const cursorPositionsOnly: [number[], number[], number[]] = [[], [], []]
141-
const replacement = /\/\*([tf\d]o?)\*\//g
141+
const replacement = /\/\*((t|f|\d+)o?)\*\//g
142142
let currentMatch: RegExpExecArray | null | undefined
143143
while ((currentMatch = replacement.exec(contents))) {
144144
const offset = currentMatch.index

0 commit comments

Comments
 (0)