From 7565c5147832d789f9f0cc4860cc9e0d8301a007 Mon Sep 17 00:00:00 2001 From: ulugbekna Date: Wed, 27 May 2026 17:03:15 +0500 Subject: [PATCH] Remove leftover code from /tests test-generation codelens The codelens feature for /tests test generation was removed in c0eaa94d6ab, but related infrastructure remained as dead code: - ITestGenInfoStorage was never populated (the deleted testGenAction.ts was the only writer), so TestFromTestInvocation and Test2Impl always took the 'undefined' branch. - IParserService.getTreeSitterAST().getTestableNode/getTestableNodes and the underlying testGenParsing helpers + testableNodeQueries had no remaining callers. Delete the storage service, the parser API, the tree-sitter queries, and the related tests. The /tests slash command itself is preserved; `_findLastTest` stays since testFromSrcInvocation.tsx still uses it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../extension/vscode-node/services.ts | 2 - .../testIntent/testFromTestInvocation.tsx | 45 +-- .../node/testIntent/testInfoStorage.ts | 34 --- .../src/extension/prompt/node/test2Impl.tsx | 25 +- .../extension/test/vscode-node/services.ts | 2 - .../src/platform/parser/node/parserImpl.ts | 2 +- .../src/platform/parser/node/parserService.ts | 6 - .../platform/parser/node/parserServiceImpl.ts | 2 - .../platform/parser/node/testGenParsing.ts | 150 +-------- .../platform/parser/node/treeSitterQueries.ts | 128 -------- .../test/node/getTestableNode.js.spec.ts | 138 --------- .../test/node/getTestableNode.ts.spec.ts | 247 --------------- .../parser/test/node/getTestableNode.util.ts | 52 ---- .../test/node/getTestableNodes.ts.spec.ts | 284 ------------------ .../parser/test/node/getTestableNodes.util.ts | 37 --- .../copilot/test/base/simulationContext.ts | 2 - 16 files changed, 11 insertions(+), 1145 deletions(-) delete mode 100644 extensions/copilot/src/extension/intents/node/testIntent/testInfoStorage.ts delete mode 100644 extensions/copilot/src/platform/parser/test/node/getTestableNode.js.spec.ts delete mode 100644 extensions/copilot/src/platform/parser/test/node/getTestableNode.ts.spec.ts delete mode 100644 extensions/copilot/src/platform/parser/test/node/getTestableNode.util.ts delete mode 100644 extensions/copilot/src/platform/parser/test/node/getTestableNodes.ts.spec.ts delete mode 100644 extensions/copilot/src/platform/parser/test/node/getTestableNodes.util.ts diff --git a/extensions/copilot/src/extension/extension/vscode-node/services.ts b/extensions/copilot/src/extension/extension/vscode-node/services.ts index ed3801b5d132e..de5209d8e6e33 100644 --- a/extensions/copilot/src/extension/extension/vscode-node/services.ts +++ b/extensions/copilot/src/extension/extension/vscode-node/services.ts @@ -113,7 +113,6 @@ import { ConversationStore, IConversationStore } from '../../conversationStore/n import { SimilarFilesContextService } from '../../inlineEdits/vscode-node/similarFilesContext'; import { IIntentService, IntentService } from '../../intents/node/intentService'; import { INewWorkspacePreviewContentManager, NewWorkspacePreviewContentManagerImpl } from '../../intents/node/newIntent'; -import { ITestGenInfoStorage, TestGenInfoStorage } from '../../intents/node/testIntent/testInfoStorage'; import { LanguageContextProviderService } from '../../languageContextProvider/vscode-node/languageContextProviderService'; import { ILinkifyService, LinkifyService } from '../../linkify/common/linkifyService'; import { DebugCommandToConfigConverter, IDebugCommandToConfigConverter } from '../../onboardDebug/node/commandToConfigConverter'; @@ -212,7 +211,6 @@ export function registerServices(builder: IInstantiationServiceBuilder, extensio builder.define(IGithubCodeSearchService, new SyncDescriptor(GithubCodeSearchService)); builder.define(IGithubAvailableEmbeddingTypesService, new SyncDescriptor(GithubAvailableEmbeddingTypesService)); - builder.define(ITestGenInfoStorage, new SyncDescriptor(TestGenInfoStorage)); // Used for test generation (/tests intent) builder.define(IParserService, new SyncDescriptor(ParserServiceImpl, [/*useWorker*/ true])); builder.define(IIntentService, new SyncDescriptor(IntentService)); builder.define(INaiveChunkingService, new SyncDescriptor(NaiveChunkingService)); diff --git a/extensions/copilot/src/extension/intents/node/testIntent/testFromTestInvocation.tsx b/extensions/copilot/src/extension/intents/node/testIntent/testFromTestInvocation.tsx index 57170b74510c1..0950a96933327 100644 --- a/extensions/copilot/src/extension/intents/node/testIntent/testFromTestInvocation.tsx +++ b/extensions/copilot/src/extension/intents/node/testIntent/testFromTestInvocation.tsx @@ -9,7 +9,6 @@ import { IResponsePart } from '../../../../platform/chat/common/chatMLFetcher'; import { ChatLocation } from '../../../../platform/chat/common/commonTypes'; import { IChatEndpoint } from '../../../../platform/networking/common/networking'; import { IParserService } from '../../../../platform/parser/node/parserService'; -import { IWorkspaceService } from '../../../../platform/workspace/common/workspaceService'; import { isNotebookCellOrNotebookChatInput } from '../../../../util/common/notebooks'; import { CancellationToken } from '../../../../util/vs/base/common/cancellation'; import { illegalArgument } from '../../../../util/vs/base/common/errors'; @@ -27,12 +26,9 @@ import { Tag } from '../../../prompts/node/base/tag'; import { ChatToolReferences, ChatVariables, UserQuery } from '../../../prompts/node/panel/chatVariables'; import { HistoryWithInstructions } from '../../../prompts/node/panel/conversationHistory'; import { CustomInstructions } from '../../../prompts/node/panel/customInstructions'; -import { CodeBlock } from '../../../prompts/node/panel/safeElements'; import { SelectionSplitKind, SummarizedDocumentData, SummarizedDocumentWithSelection } from './summarizedDocumentWithSelection'; import { TestDeps } from './testDeps'; -import { ITestGenInfo, ITestGenInfoStorage } from './testInfoStorage'; import { TestsIntent } from './testIntent'; -import { formatRequestAndUserQuery } from './testPromptUtil'; import { PseudoStopStartResponseProcessor } from '../../../prompt/node/pseudoStartStopConversationCallback'; @@ -50,7 +46,6 @@ export class TestFromTestInvocation implements IIntentInvocation { private readonly context: IDocumentContext, private readonly alreadyConsumedChatVariable: vscode.ChatPromptReference | undefined, @IInstantiationService private readonly instantiationService: IInstantiationService, - @ITestGenInfoStorage private readonly testGenInfoStorage: ITestGenInfoStorage, ) { } @@ -61,12 +56,6 @@ export class TestFromTestInvocation implements IIntentInvocation { >, token: vscode.CancellationToken ) { - const testGenInfo = this.testGenInfoStorage.sourceFileToTest; - - if (testGenInfo !== undefined) { - this.testGenInfoStorage.sourceFileToTest = undefined; - } - const renderer = PromptRenderer.create( this.instantiationService, this.endpoint, @@ -75,7 +64,6 @@ export class TestFromTestInvocation implements IIntentInvocation { context: this.context, promptContext, alreadyConsumedChatVariable: this.alreadyConsumedChatVariable, - testGenInfo, } ); @@ -114,14 +102,12 @@ type Props = PromptElementProps<{ context: IDocumentContext; promptContext: IBuildPromptContext; alreadyConsumedChatVariable: vscode.ChatPromptReference | undefined; - testGenInfo: ITestGenInfo | undefined; }>; class TestFromTestPrompt extends PromptElement { constructor( props: Props, - @IWorkspaceService private readonly workspaceService: IWorkspaceService, @IParserService private readonly parserService: IParserService ) { super(props); @@ -130,32 +116,13 @@ class TestFromTestPrompt extends PromptElement { override async render(_state: void, sizing: PromptSizing) { const { history, query, chatVariables, } = this.props.promptContext; - const { context, testGenInfo, alreadyConsumedChatVariable, } = this.props; + const { context, alreadyConsumedChatVariable, } = this.props; if (isNotebookCellOrNotebookChatInput(context.document.uri)) { throw illegalArgument('TestFromTestPrompt should not be used for notebooks'); } - const testedSymbolIdentifier = testGenInfo?.identifier; - - const requestAndUserQuery = testGenInfo === undefined - ? `Please, generate more tests, taking into account existing tests. ${query}`.trim() - : formatRequestAndUserQuery({ - workspaceService: this.workspaceService, - chatVariables, - userQuery: query, - testFileToWriteTo: context.document.uri, - testedSymbolIdentifier, - context, - }); - - let testedDeclarationExcerpt = undefined; - if (testGenInfo !== undefined) { - const srcFileDoc = await this.workspaceService.openTextDocument(testGenInfo.uri); - const declStart = testGenInfo.target.start; - const expandedRange = testGenInfo.target.with(declStart.with(declStart.line, 0)); - testedDeclarationExcerpt = srcFileDoc.getText(expandedRange); - } + const requestAndUserQuery = `Please, generate more tests, taking into account existing tests. ${query}`.trim(); const data = await SummarizedDocumentData.create( this.parserService, @@ -190,7 +157,7 @@ class TestFromTestPrompt extends PromptElement { {/* include summarized source file: */} - + {/* include summarized test file: */} { tokenBudget={sizing.tokenBudget / 3} _allowEmptySelection={true} />{ /* FIXME@ulugbekna: rework summarization to be more intelligent */} - {/* repeat tested declaration -- otherwise, model seems to forget it: */} - {testGenInfo !== undefined && testedDeclarationExcerpt !== undefined && /* FIXME@ulugbekna: include class around */ - - {`Repeating excerpt from \`${testGenInfo?.uri.path}\` here that needs to be tested:`}{/* FIXME@ulugbekna */}
- -
} diff --git a/extensions/copilot/src/extension/intents/node/testIntent/testInfoStorage.ts b/extensions/copilot/src/extension/intents/node/testIntent/testInfoStorage.ts deleted file mode 100644 index e6a63e8357a1e..0000000000000 --- a/extensions/copilot/src/extension/intents/node/testIntent/testInfoStorage.ts +++ /dev/null @@ -1,34 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createServiceIdentifier } from '../../../../util/common/services'; -import { URI } from '../../../../util/vs/base/common/uri'; -import { Range } from '../../../../vscodeTypes'; - - -export const ITestGenInfoStorage = createServiceIdentifier('ITestGenInfoStorage'); - -export interface ITestGenInfo { - uri: URI; - target: Range; - identifier: string | undefined; -} - -/** - * Global storage for test generation information that allows data flow between - * test gen entry points such as (context menu item and code action) and an inline chat that - * are created from those entry points. - */ -export interface ITestGenInfoStorage { - readonly _serviceBrand: undefined; - - sourceFileToTest: ITestGenInfo | undefined; -} - -export class TestGenInfoStorage implements ITestGenInfoStorage { - declare _serviceBrand: undefined; - - sourceFileToTest = undefined; -} diff --git a/extensions/copilot/src/extension/prompt/node/test2Impl.tsx b/extensions/copilot/src/extension/prompt/node/test2Impl.tsx index 9883663ae5b77..32a9e31e18dca 100644 --- a/extensions/copilot/src/extension/prompt/node/test2Impl.tsx +++ b/extensions/copilot/src/extension/prompt/node/test2Impl.tsx @@ -5,13 +5,10 @@ import { PromptElement, PromptElementProps, PromptSizing } from '@vscode/prompt-tsx'; import assert from 'assert'; -import type * as vscode from 'vscode'; import { IIgnoreService } from '../../../platform/ignore/common/ignoreService'; import { IWorkspaceService } from '../../../platform/workspace/common/workspaceService'; import { CancellationToken } from '../../../util/vs/base/common/cancellation'; -import { URI } from '../../../util/vs/base/common/uri'; import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation'; -import { ITestGenInfo } from '../../intents/node/testIntent/testInfoStorage'; import { Tag } from '../../prompts/node/base/tag'; import { DocumentSummarizer } from '../../prompts/node/inline/summarizedDocument/summarizeDocumentHelpers'; import { CodeBlock } from '../../prompts/node/panel/safeElements'; @@ -24,10 +21,6 @@ type Props = PromptElementProps<{ * Document here is expected to be a test file. */ documentContext: IDocumentContext; - /** - * Src (ie impl) file to include if already known. - */ - srcFile?: ITestGenInfo; }>; /** @@ -46,21 +39,13 @@ export class Test2Impl extends PromptElement { override async render(state: void, sizing: PromptSizing) { - const { documentContext, srcFile, } = this.props; + const { documentContext } = this.props; assert(isTestFile(documentContext.document), 'Test2Impl must be invoked on a test file.'); - let candidateFile: URI | undefined; - let selection: vscode.Range | undefined; - - if (srcFile) { - candidateFile = srcFile.uri; - selection = srcFile.target; - } else { - // @ulugbekna: find file that this test file corresponds to - const finder = this.instaService.createInstance(TestFileFinder); - candidateFile = await finder.findFileForTestFile(documentContext.document, CancellationToken.None); - } + // @ulugbekna: find file that this test file corresponds to + const finder = this.instaService.createInstance(TestFileFinder); + const candidateFile = await finder.findFileForTestFile(documentContext.document, CancellationToken.None); if (candidateFile === undefined || await this.ignoreService.isCopilotIgnored(candidateFile)) { return undefined; @@ -73,7 +58,7 @@ export class Test2Impl extends PromptElement { const summarizedDoc = await docSummarizer.summarizeDocument( doc, documentContext.fileIndentInfo, - selection, + undefined, sizing.tokenBudget, ); diff --git a/extensions/copilot/src/extension/test/vscode-node/services.ts b/extensions/copilot/src/extension/test/vscode-node/services.ts index 81985b4765a90..bbf18d8279687 100644 --- a/extensions/copilot/src/extension/test/vscode-node/services.ts +++ b/extensions/copilot/src/extension/test/vscode-node/services.ts @@ -101,7 +101,6 @@ import { ICopilotInlineCompletionItemProviderService, NullCopilotInlineCompletio import { IPromptWorkspaceLabels, PromptWorkspaceLabels } from '../../context/node/resolvers/promptWorkspaceLabels'; import { IUserFeedbackService, UserFeedbackService } from '../../conversation/vscode-node/userActions'; import { ConversationStore, IConversationStore } from '../../conversationStore/node/conversationStore'; -import { ITestGenInfoStorage, TestGenInfoStorage } from '../../intents/node/testIntent/testInfoStorage'; import { ILinkifyService, LinkifyService } from '../../linkify/common/linkifyService'; import { ILaunchConfigService } from '../../onboardDebug/common/launchConfigService'; import { DebugCommandToConfigConverter, IDebugCommandToConfigConverter } from '../../onboardDebug/node/commandToConfigConverter'; @@ -176,7 +175,6 @@ export function createExtensionTestingServices(): TestingServiceCollection { testingServiceCollection.define(ITestProvider, new SyncDescriptor(TestProvider)); testingServiceCollection.define(INaiveChunkingService, new SyncDescriptor(NaiveChunkingService)); testingServiceCollection.define(ILinkifyService, new SyncDescriptor(LinkifyService)); - testingServiceCollection.define(ITestGenInfoStorage, new SyncDescriptor(TestGenInfoStorage)); testingServiceCollection.define(IEditToolLearningService, new SyncDescriptor(EditToolLearningService)); testingServiceCollection.define(IDebugCommandToConfigConverter, new SyncDescriptor(DebugCommandToConfigConverter)); testingServiceCollection.define(ILaunchConfigService, new SyncDescriptor(LaunchConfigService)); diff --git a/extensions/copilot/src/platform/parser/node/parserImpl.ts b/extensions/copilot/src/platform/parser/node/parserImpl.ts index 64230a59a2305..d6a04eb7d5b97 100644 --- a/extensions/copilot/src/platform/parser/node/parserImpl.ts +++ b/extensions/copilot/src/platform/parser/node/parserImpl.ts @@ -18,7 +18,7 @@ import Parser = require('web-tree-sitter'); export { _getDocumentableNodeIfOnIdentifier, _getNodeToDocument, NodeToDocumentContext } from './docGenParsing'; export { _dispose } from './parserWithCaching'; export { _getNodeMatchingSelection } from './selectionParsing'; -export { _findLastTest, _getTestableNode, _getTestableNodes } from './testGenParsing'; +export { _findLastTest } from './testGenParsing'; function queryCoarseScopes(language: WASMLanguage, root: Parser.SyntaxNode): Parser.QueryMatch[] { const queries = coarseScopesQuery[language]; diff --git a/extensions/copilot/src/platform/parser/node/parserService.ts b/extensions/copilot/src/platform/parser/node/parserService.ts index 22ff28e839251..4c5d1851dab49 100644 --- a/extensions/copilot/src/platform/parser/node/parserService.ts +++ b/extensions/copilot/src/platform/parser/node/parserService.ts @@ -10,7 +10,6 @@ import { TextDocumentSnapshot } from '../../editing/common/textDocumentSnapshot' import { BlockNameDetail, DetailBlock, QueryMatchTree } from './chunkGroupTypes'; import { OverlayNode, TreeSitterExpressionInfo, TreeSitterOffsetRange, TreeSitterPointRange } from './nodes'; import type * as parser from './parserImpl'; -import { TestableNode } from './testGenParsing'; import { WASMLanguage } from './treeSitterLanguages'; export const IParserService = createServiceIdentifier('IParserService'); @@ -60,11 +59,6 @@ export interface TreeSitterAST { * @param range The range to document. */ getDocumentableNodeIfOnIdentifier(range: TreeSitterOffsetRange): Promise<{ identifier: string; nodeRange?: TreeSitterOffsetRange } | undefined>; - /** - * @param range The range to test. - */ - getTestableNode(range: TreeSitterOffsetRange): Promise; - getTestableNodes(): Promise; /** * Starting from the smallest AST node that wraps `selection` and climbs up the AST until it sees a "documentable" node. * See {@link isDocumentableNode} for definition of a "documentable" node. diff --git a/extensions/copilot/src/platform/parser/node/parserServiceImpl.ts b/extensions/copilot/src/platform/parser/node/parserServiceImpl.ts index b4cc637ab9d9d..9ef6b70be426b 100644 --- a/extensions/copilot/src/platform/parser/node/parserServiceImpl.ts +++ b/extensions/copilot/src/platform/parser/node/parserServiceImpl.ts @@ -52,8 +52,6 @@ export class ParserServiceImpl implements IParserService { getTypeReferences: (selection: TreeSitterOffsetRange) => parserProxy._getTypeReferences(wasmLanguage, source, selection), getSymbols: (selection: TreeSitterOffsetRange) => parserProxy._getSymbols(wasmLanguage, source, selection), getDocumentableNodeIfOnIdentifier: (range: TreeSitterOffsetRange) => parserProxy._getDocumentableNodeIfOnIdentifier(wasmLanguage, source, range), - getTestableNode: (range: TreeSitterOffsetRange) => parserProxy._getTestableNode(wasmLanguage, source, range), - getTestableNodes: () => parserProxy._getTestableNodes(wasmLanguage, source), getNodeToExplain: (range: TreeSitterOffsetRange) => parserProxy._getNodeToExplain(wasmLanguage, source, range), getNodeToDocument: (range: TreeSitterOffsetRange) => parserProxy._getNodeToDocument(wasmLanguage, source, range), getFineScopes: (selection: TreeSitterOffsetRange) => parserProxy._getFineScopes(wasmLanguage, source, selection), diff --git a/extensions/copilot/src/platform/parser/node/testGenParsing.ts b/extensions/copilot/src/platform/parser/node/testGenParsing.ts index de985162636b9..1f17e9bc35c12 100644 --- a/extensions/copilot/src/platform/parser/node/testGenParsing.ts +++ b/extensions/copilot/src/platform/parser/node/testGenParsing.ts @@ -3,157 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { QueryCapture } from 'web-tree-sitter'; -import { uniqueFilter } from '../../../util/vs/base/common/arrays'; -import { assertType } from '../../../util/vs/base/common/types'; -import { Node, TreeSitterOffsetRange } from './nodes'; +import { TreeSitterOffsetRange } from './nodes'; import { _parse } from './parserWithCaching'; import { runQueries } from './querying'; import { WASMLanguage } from './treeSitterLanguages'; -import { testableNodeQueries, testInSuiteQueries } from './treeSitterQueries'; - -export type TestableNode = { - identifier: { - name: string; - range: TreeSitterOffsetRange; - }; - node: Node; -}; - - -export async function _getTestableNode( - language: WASMLanguage, - source: string, - range: TreeSitterOffsetRange -): Promise { - const treeRef = await _parse(language, source); - - try { - const queryCaptures = runQueries( - testableNodeQueries[language], - treeRef.tree.rootNode - ).flatMap(({ captures }) => captures); // @ulugbekna: keep in mind: there's duplication of captures - - const symbolKindToIdents = new Map(); - - for (const capture of queryCaptures) { - const [symbolKind, name] = capture.name.split('.'); - if (name !== 'identifier') { - continue; - } - - const idents = symbolKindToIdents.get(symbolKind) || []; - idents.push(capture); - symbolKindToIdents.set(symbolKind, idents); - } - - let minimalTestableNode: TestableNode | null = null; - - for (const capture of queryCaptures) { - const [symbolKind, name] = capture.name.split('.'); - - if (name !== undefined || // ensure we traverse only declarations (and child nodes such as `method.identifier` or `method.accessibility_modifier`) - !TreeSitterOffsetRange.doesContain(capture.node, range) // ensure this declaration contains our range of interest - ) { - continue; - } - - // ensure we pick range-wise minimal testable node - if (minimalTestableNode !== null && - TreeSitterOffsetRange.len(minimalTestableNode.node) < TreeSitterOffsetRange.len(capture.node) - ) { - continue; - } - - const idents = symbolKindToIdents.get(symbolKind); - - assertType(idents !== undefined, `must have seen identifier for symbol kind '${symbolKind}' (lang: ${language})`); - - const nodeIdent = idents.find(ident => TreeSitterOffsetRange.doesContain(capture.node, ident.node)); - - assertType(nodeIdent !== undefined, `must have seen identifier for symbol '${symbolKind}' (lang: ${language})`); - - minimalTestableNode = { - identifier: { - name: nodeIdent.node.text, - range: TreeSitterOffsetRange.ofSyntaxNode(nodeIdent.node), - }, - node: Node.ofSyntaxNode(capture.node), - }; - } - - return minimalTestableNode; - - } catch (e) { - console.error('getTestableNode: Unexpected error', e); - return null; - } finally { - treeRef.dispose(); - } -} - -export async function _getTestableNodes( - language: WASMLanguage, - source: string, -): Promise { - const treeRef = await _parse(language, source); - - try { - const queryCaptures = runQueries( - testableNodeQueries[language], - treeRef.tree.rootNode - ) - .flatMap(({ captures }) => captures) - .filter(uniqueFilter((c: QueryCapture) => [c.node.startIndex, c.node.endIndex].toString())); - - const symbolKindToIdents = new Map(); - - for (const capture of queryCaptures) { - const [symbolKind, name] = capture.name.split('.'); - if (name !== 'identifier') { - continue; - } - - const idents = symbolKindToIdents.get(symbolKind) || []; - idents.push(capture); - symbolKindToIdents.set(symbolKind, idents); - } - - const testableNodes: TestableNode[] = []; - - for (const capture of queryCaptures) { - if (capture.name.includes('.')) { - continue; - } - - const symbolKind = capture.name; - - const idents = symbolKindToIdents.get(symbolKind); - - assertType(idents !== undefined, `must have seen identifier for symbol kind '${symbolKind}' (lang: ${language})`); - - const nodeIdent = idents.find(ident => TreeSitterOffsetRange.doesContain(capture.node, ident.node)); - - assertType(nodeIdent !== undefined, `must have seen identifier for symbol '${symbolKind}' (lang: ${language})`); - - testableNodes.push({ - identifier: { - name: nodeIdent.node.text, - range: TreeSitterOffsetRange.ofSyntaxNode(nodeIdent.node), - }, - node: Node.ofSyntaxNode(capture.node), - }); - } - - return testableNodes; - - } catch (e) { - console.error('getTestableNodes: Unexpected error', e); - return null; - } finally { - treeRef.dispose(); - } -} +import { testInSuiteQueries } from './treeSitterQueries'; export async function _findLastTest(lang: WASMLanguage, src: string): Promise { diff --git a/extensions/copilot/src/platform/parser/node/treeSitterQueries.ts b/extensions/copilot/src/platform/parser/node/treeSitterQueries.ts index c1c73fd6d25fa..fad2a68bb4ad7 100644 --- a/extensions/copilot/src/platform/parser/node/treeSitterQueries.ts +++ b/extensions/copilot/src/platform/parser/node/treeSitterQueries.ts @@ -480,134 +480,6 @@ export const docCommentQueries: LanguageQueryMap = q({ ], }); -export const testableNodeQueries: LanguageQueryMap = q({ - [WASMLanguage.JavaScript]: [ - treeSitterQuery.javascript`[ - (function_declaration - (identifier) @function.identifier - ) @function - - (generator_function_declaration - name: (identifier) @generator_function.identifier - ) @generator_function - - (class_declaration - name: (identifier) @class.identifier ;; note: (type_identifier) in typescript - body: (class_body - (method_definition - name: (property_identifier) @method.identifier - ) @method - ) - ) @class - ]` - ], - ...forLanguages([WASMLanguage.TypeScript, WASMLanguage.TypeScriptTsx], - [treeSitterQuery.typescript`[ - (function_declaration - (identifier) @function.identifier - ) @function - - (generator_function_declaration - name: (identifier) @generator_function.identifier - ) @generator_function - - (class_declaration - name: (type_identifier) @class.identifier - body: (class_body - (method_definition - (accessibility_modifier)? @method.accessibility_modifier - name: (property_identifier) @method.identifier - (#not-eq? @method.accessibility_modifier "private") - ) @method - ) - ) @class - ]`] - ), - [WASMLanguage.Python]: [ - treeSitterQuery.python`[ - (function_definition - name: (identifier) @function.identifier - ) @function - ]` - ], - [WASMLanguage.Go]: [ - treeSitterQuery.go`[ - (function_declaration - name: (identifier) @function.identifier - ) @function - - (method_declaration - name: (field_identifier) @method.identifier - ) @method - ]` - ], - [WASMLanguage.Ruby]: [ - treeSitterQuery.ruby`[ - (method - name: (identifier) @method.identifier - ) @method - - (singleton_method - name: (_) @singleton_method.identifier - ) @singleton_method - ]` - ], - [WASMLanguage.Csharp]: [ - treeSitterQuery.csharp`[ - (constructor_declaration - (identifier) @constructor.identifier - ) @constructor - - (destructor_declaration - (identifier) @destructor.identifier - ) @destructor - - (method_declaration - (identifier) @method.identifier - ) @method - - (local_function_statement - (identifier) @local_function.identifier - ) @local_function - ]` - ], - [WASMLanguage.Cpp]: [ // FIXME@ulugbekna: #7769 enrich with class/methods - treeSitterQuery.cpp`[ - (function_definition - (_ - (identifier) @identifier) - ) @function - ]` - ], - [WASMLanguage.Java]: [ - treeSitterQuery.java`(class_declaration - name: (_) @class.identifier - body: (_ - [ - (constructor_declaration - (modifiers)? @constructor.modifiers - (#not-eq? @constructor.modifiers "private") - name: (identifier) @constructor.identifier - ) @constructor - - (method_declaration - (modifiers)? @method.modifiers - (#not-eq? @method.modifiers "private") - name: (identifier) @method.identifier - ) @method - ] - ) - ) @class` - ], - [WASMLanguage.Rust]: [ - treeSitterQuery.rust`[ - (function_item - (identifier) @function.identifier - ) @function - ]` - ] -}); - export const symbolQueries: LanguageQueryMap = q({ [WASMLanguage.JavaScript]: [ treeSitterQuery.javascript`[ diff --git a/extensions/copilot/src/platform/parser/test/node/getTestableNode.js.spec.ts b/extensions/copilot/src/platform/parser/test/node/getTestableNode.js.spec.ts deleted file mode 100644 index 651ffaabb0b3c..0000000000000 --- a/extensions/copilot/src/platform/parser/test/node/getTestableNode.js.spec.ts +++ /dev/null @@ -1,138 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { outdent } from 'outdent'; -import { afterAll, expect, suite, test } from 'vitest'; -import { _dispose } from '../../node/parserWithCaching'; -import { WASMLanguage } from '../../node/treeSitterLanguages'; -import { srcWithAnnotatedTestableNode } from './getTestableNode.util'; - -suite('getTestableNode - js', () => { - afterAll(() => _dispose()); - - function run(annotatedSrc: string) { - return srcWithAnnotatedTestableNode( - WASMLanguage.JavaScript, - annotatedSrc, - ); - } - - test('function declaration', async () => { - const result = await run( - outdent` - function <>(a: number, b: number): number { - return a + b; - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "function add(a: number, b: number): number { - return a + b; - }" - `); - }); - - test('method', async () => { - const result = await run( - outdent` - class Foo { - <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('public method', async () => { - const result = await run( - outdent` - class Foo { - <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('does not capture private method', async () => { - const result = await run( - outdent` - class Foo { - private <<#method>>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(`"testable node NOT found"`); - }); - - test('static method', async () => { - const result = await run( - outdent` - class Foo { - static <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('private static method', async () => { - const result = await run( - outdent` - class Foo { - static <<#method>>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(`"testable node NOT found"`); - }); - - test('public static method', async () => { - const result = await run( - outdent` - class Foo { - public static <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - public static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); -}); diff --git a/extensions/copilot/src/platform/parser/test/node/getTestableNode.ts.spec.ts b/extensions/copilot/src/platform/parser/test/node/getTestableNode.ts.spec.ts deleted file mode 100644 index 8f60da9b0bc24..0000000000000 --- a/extensions/copilot/src/platform/parser/test/node/getTestableNode.ts.spec.ts +++ /dev/null @@ -1,247 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { outdent } from 'outdent'; -import { afterAll, expect, suite, test } from 'vitest'; -import { _dispose } from '../../node/parserWithCaching'; -import { WASMLanguage } from '../../node/treeSitterLanguages'; -import { srcWithAnnotatedTestableNode } from './getTestableNode.util'; - -suite('getTestableNode - ts', () => { - afterAll(() => _dispose()); - - function run(annotatedSrc: string) { - return srcWithAnnotatedTestableNode( - WASMLanguage.TypeScript, - annotatedSrc, - ); - } - - test('function declaration', async () => { - const result = await run( - outdent` - function <>(a: number, b: number): number { - return a + b; - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "function add(a: number, b: number): number { - return a + b; - }" - `); - }); - - test('method', async () => { - const result = await run( - outdent` - class Foo { - <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('public method', async () => { - const result = await run( - outdent` - class Foo { - <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('several public methods', async () => { - const result = await run( - outdent` - class Foo { - method(a: number, b: number): number { - return a + b; - } - - method2(a: number, b: number): number { - return a + b; - } - - method3(a: number, b: number): number { - return a + b; - } - - <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - method(a: number, b: number): number { - return a + b; - } - - method2(a: number, b: number): number { - return a + b; - } - - method3(a: number, b: number): number { - return a + b; - } - - method4(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('does not capture private method', async () => { - const result = await run( - outdent` - class Foo { - private <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(`"testable node NOT found"`); - }); - - test('static method', async () => { - const result = await run( - outdent` - class Foo { - static <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('private static method', async () => { - const result = await run( - outdent` - class Foo { - private static <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(`"testable node NOT found"`); - }); - - - test('public static method', async () => { - const result = await run( - outdent` - class Foo { - public static <>(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - public static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('class declaration', async () => { - const result = await run( - outdent` - export class <<>>Foo { - method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "export class Foo { - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('class declaration with prop and method', async () => { - const result = await run( - outdent` - export class <<>>Foo { - bar = 1; - - method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "export class Foo { - bar = 1; - - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('class declaration with prop and static method', async () => { - const result = await run( - outdent` - export class Foo { - bar = 1; - - static <<>>method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "export class Foo { - bar = 1; - - static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); -}); diff --git a/extensions/copilot/src/platform/parser/test/node/getTestableNode.util.ts b/extensions/copilot/src/platform/parser/test/node/getTestableNode.util.ts deleted file mode 100644 index b6d2f3366d039..0000000000000 --- a/extensions/copilot/src/platform/parser/test/node/getTestableNode.util.ts +++ /dev/null @@ -1,52 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { deannotateSrc } from '../../../../util/common/test/annotatedSrc'; -import { _getTestableNode } from '../../node/testGenParsing'; -import { WASMLanguage } from '../../node/treeSitterLanguages'; -import { insertRangeMarkers, MarkerRange } from './markers'; - -export async function srcWithAnnotatedTestableNode(language: WASMLanguage, source: string, includeSelection = false) { - const { deannotatedSrc, annotatedRange: selection } = deannotateSrc(source); - - const result = await _getTestableNode( - language, - deannotatedSrc, - selection - ); - - if (result === null) { - return 'testable node NOT found'; - } - - const markers: MarkerRange[] = []; - - const ident = result.identifier; - markers.push({ - startIndex: ident.range.startIndex, - endIndex: ident.range.endIndex, - kind: 'IDENT', - }); - - if (includeSelection) { - markers.push( - { - startIndex: selection.startIndex, - endIndex: selection.endIndex, - kind: 'SELECTION' - } - ); - } - - markers.push( - { - startIndex: result.node.startIndex, - endIndex: result.node.endIndex, - kind: `NODE(${result.node.type})`, - } - ); - - return insertRangeMarkers(deannotatedSrc, markers); -} diff --git a/extensions/copilot/src/platform/parser/test/node/getTestableNodes.ts.spec.ts b/extensions/copilot/src/platform/parser/test/node/getTestableNodes.ts.spec.ts deleted file mode 100644 index 6eb9e2d7a2bc3..0000000000000 --- a/extensions/copilot/src/platform/parser/test/node/getTestableNodes.ts.spec.ts +++ /dev/null @@ -1,284 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { outdent } from 'outdent'; -import { afterAll, expect, suite, test } from 'vitest'; -import { _dispose } from '../../node/parserWithCaching'; -import { WASMLanguage } from '../../node/treeSitterLanguages'; -import { annotTestableNodes } from './getTestableNodes.util'; - -suite('getTestableNodes - ts', () => { - afterAll(() => _dispose()); - - function run(annotatedSrc: string) { - return annotTestableNodes( - WASMLanguage.TypeScript, - annotatedSrc, - ); - } - - test('function declaration', async () => { - const result = await run( - outdent` - function add(a: number, b: number): number { - return a + b; - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "function add(a: number, b: number): number { - return a + b; - }" - `); - }); - - test('method', async () => { - const result = await run( - outdent` - class Foo { - method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('public method', async () => { - const result = await run( - outdent` - class Foo { - method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('several public methods', async () => { - const result = await run( - outdent` - class Foo { - method(a: number, b: number): number { - return a + b; - } - - method2(a: number, b: number): number { - return a + b; - } - - method3(a: number, b: number): number { - return a + b; - } - - method4(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - method(a: number, b: number): number { - return a + b; - } - - method2(a: number, b: number): number { - return a + b; - } - - method3(a: number, b: number): number { - return a + b; - } - - method4(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('captures mix', async () => { - const result = await run( - outdent` - class Foo { - methodPub() { - } - - private method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - methodPub() { - } - - private method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('does NOT capture private method', async () => { - const result = await run( - outdent` - class Foo { - private method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - private method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('static method', async () => { - const result = await run( - outdent` - class Foo { - static method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('private static method', async () => { - const result = await run( - outdent` - class Foo { - private static method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - private static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - - test('public static method', async () => { - const result = await run( - outdent` - class Foo { - public static method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "class Foo { - public static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('class declaration', async () => { - const result = await run( - outdent` - export class Foo { - method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "export class Foo { - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('class declaration with prop and method', async () => { - const result = await run( - outdent` - export class Foo { - bar = 1; - - method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "export class Foo { - bar = 1; - - method(a: number, b: number): number { - return a + b; - } - }" - `); - }); - - test('class declaration with prop and static method', async () => { - const result = await run( - outdent` - export class Foo { - bar = 1; - - static method(a: number, b: number): number { - return a + b; - } - } - `, - ); - expect(result).toMatchInlineSnapshot(` - "export class Foo { - bar = 1; - - static method(a: number, b: number): number { - return a + b; - } - }" - `); - }); -}); diff --git a/extensions/copilot/src/platform/parser/test/node/getTestableNodes.util.ts b/extensions/copilot/src/platform/parser/test/node/getTestableNodes.util.ts deleted file mode 100644 index 1edc04a5b2c10..0000000000000 --- a/extensions/copilot/src/platform/parser/test/node/getTestableNodes.util.ts +++ /dev/null @@ -1,37 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { _getTestableNodes } from '../../node/testGenParsing'; -import { WASMLanguage } from '../../node/treeSitterLanguages'; -import { insertRangeMarkers } from './markers'; - -export async function annotTestableNodes(language: WASMLanguage, source: string, includeSelection = false) { - - const result = await _getTestableNodes( - language, - source, - ); - - if (result === null) { - return 'testable node NOT found'; - } - - const markers = result.flatMap(node => { - return [ - { - startIndex: node.node.startIndex, - endIndex: node.node.endIndex, - kind: 'NODE', - }, - { - startIndex: node.identifier.range.startIndex, - endIndex: node.identifier.range.endIndex, - kind: 'IDENT', - } - ]; - }); - - return insertRangeMarkers(source, markers); -} diff --git a/extensions/copilot/test/base/simulationContext.ts b/extensions/copilot/test/base/simulationContext.ts index f11a38764fedd..7d74cb7a46cf2 100644 --- a/extensions/copilot/test/base/simulationContext.ts +++ b/extensions/copilot/test/base/simulationContext.ts @@ -8,7 +8,6 @@ import path from 'path'; import { ApiEmbeddingsIndex, IApiEmbeddingsIndex } from '../../src/extension/context/node/resolvers/extensionApi'; import { ConversationStore, IConversationStore } from '../../src/extension/conversationStore/node/conversationStore'; import { IIntentService, IntentService } from '../../src/extension/intents/node/intentService'; -import { ITestGenInfoStorage, TestGenInfoStorage } from '../../src/extension/intents/node/testIntent/testInfoStorage'; import { ILinkifyService, LinkifyService } from '../../src/extension/linkify/common/linkifyService'; import { ChatMLFetcherImpl } from '../../src/extension/prompt/node/chatMLFetcher'; import { createExtensionUnitTestingServices, ISimulationModelConfig } from '../../src/extension/test/node/services'; @@ -288,7 +287,6 @@ export async function createSimulationAccessor( testingServiceCollection.define(INaiveChunkingService, new SyncDescriptor(NaiveChunkingService)); testingServiceCollection.define(ILinkifyService, new SyncDescriptor(LinkifyService)); testingServiceCollection.define(ITestProvider, new SyncDescriptor(NullTestProvider)); - testingServiceCollection.define(ITestGenInfoStorage, new SyncDescriptor(TestGenInfoStorage)); testingServiceCollection.define(IConversationStore, new SyncDescriptor(ConversationStore)); testingServiceCollection.define(IReviewService, new SyncDescriptor(SimulationReviewService)); testingServiceCollection.define(IGitExtensionService, new SyncDescriptor(NullGitExtensionService));