diff --git a/src/templates/callTemplate.ts b/src/templates/callTemplate.ts index 5d99c93..c41a325 100644 --- a/src/templates/callTemplate.ts +++ b/src/templates/callTemplate.ts @@ -1,4 +1,4 @@ -import { Node } from "typescript" +import * as ts from "typescript" import { IndentInfo } from "../template" import { BaseTemplate } from "./baseTemplates" import { CompletionItemBuilder } from "../completionItemBuilder" @@ -8,19 +8,23 @@ export class CallTemplate extends BaseTemplate { super(keyword) } - override buildCompletionItem(node: Node, indentInfo?: IndentInfo) { + override buildCompletionItem(node: ts.Node, indentInfo?: IndentInfo) { return CompletionItemBuilder.create(this.keyword, node, indentInfo) .replace('$0({{expr}})') .build() } - override canUse(node: Node) { + override canUse(node: ts.Node) { return !this.inIfStatement(node) && !this.isTypeNode(node) && (this.isIdentifier(node) || this.isExpression(node) || this.isNewExpression(node) || this.isUnaryExpression(node) || this.isBinaryExpression(node) || - this.isCallExpression(node)) + this.isCallExpression(node) || + // Support function expressions and arrow functions (but not method declarations) + // Note: We can't use isAnyFunction() as it includes method declarations + ts.isFunctionExpression(node) || + ts.isArrowFunction(node)) } } diff --git a/test/extension.multiline.test.ts b/test/extension.multiline.test.ts index 2e9c496..1f3aaec 100644 --- a/test/extension.multiline.test.ts +++ b/test/extension.multiline.test.ts @@ -80,6 +80,11 @@ describe('Multiline template tests', () => { | \t2, >> \t2, | \t3){return} >> \t3)`) + Test(`call template - async function expression + | async function() { >> (async function() { + | \treturn true >> \treturn true + | }{call} >> })`) + describe('Without {{expr}}', () => { const run = runWithCustomTemplate('1\n\t1\n1') diff --git a/test/extension.singleline.test.ts b/test/extension.singleline.test.ts index b7e099f..a1f643c 100644 --- a/test/extension.singleline.test.ts +++ b/test/extension.singleline.test.ts @@ -78,6 +78,10 @@ describe('Single line template tests', () => { Test('cast template | expr{cast} >> (<>expr)') Test('castas template | expr{castas} >> (expr as )') Test('call template | expr{call} >> (expr)') + Test('call template - function expression | function(){}{call} >> (function(){})') + Test('call template - async function expression | async function(){}{call} >> (async function(){})') + Test('call template - arrow function | ()=>{}{call} >> (()=>{})') + Test('call template - async arrow function | async ()=>{}{call} >> (async ()=>{})') Test('new template - identifier | Type{new} >> new Type()') Test('new template - property access expression | namespace.Type{new} >> new namespace.Type()') diff --git a/test/template.usage.test.ts b/test/template.usage.test.ts index ccfabde..d9c1bfc 100644 --- a/test/template.usage.test.ts +++ b/test/template.usage.test.ts @@ -66,6 +66,10 @@ describe('Template usage', () => { testTemplateUsage('object literal expression', '{foo:"foo"}', [...VAR_TEMPLATES, ...CONSOLE_TEMPLATES, 'return']) testTemplateUsage('new expression', 'new Class()', [...VAR_TEMPLATES, ...CONSOLE_TEMPLATES, ...CAST_TEMPLATES, 'return', 'call']) testTemplateUsage('expression as argument', 'function.call("arg", expr{cursor})', [...CAST_TEMPLATES, 'not', 'new', 'await', 'call']) + testTemplateUsage('function expression', 'function(){}', ['call']) + testTemplateUsage('async function expression', 'async function(){}', ['call']) + testTemplateUsage('arrow function', '()=>{}', ['call']) + testTemplateUsage('async arrow function', 'async ()=>{}', ['call']) testTemplateUsage('string literal - single quote', '\'a string\'', STRING_LITERAL_TEMPLATES) testTemplateUsage('string literal - double quote', '"a string"', STRING_LITERAL_TEMPLATES)